浏览代码

ENH: Better support for adding and removing path

Andy Cedilnik 19 年之前
父节点
当前提交
8d2c78f43c
共有 1 个文件被更改,包括 180 次插入140 次删除
  1. 180 140
      Modules/NSIS.template.in

+ 180 - 140
Modules/NSIS.template.in

@@ -81,168 +81,208 @@ FunctionEnd
 !verbose 3
 !include "WinMessages.NSH"
 !verbose 4
- 
+
+;----------------------------------------
+; based upon a script of "Written by KiCHiK 2003-01-18 05:57:02"
+;----------------------------------------
+!verbose 3
+!include "WinMessages.NSH"
+!verbose 4
+;====================================================
+; get_NT_environment 
+;     Returns: the selected environment
+;     Output : head of the stack
+;====================================================
+!macro select_NT_profile UN
+Function ${UN}select_NT_profile
+   MessageBox MB_YESNO|MB_ICONQUESTION "Change the environment for all users? $\n\
+$\n\
+Saying no here will change the envrironment for the current user only. $\n\
+$\n\
+(Administrator permissions required for all users)" \
+      IDNO environment_single
+      DetailPrint "Selected environment for all users"
+      Push "all"
+      Return
+   environment_single:
+      DetailPrint "Selected environment for current user only."
+      Push "current"
+      Return
+FunctionEnd
+!macroend
+!insertmacro select_NT_profile ""
+!insertmacro select_NT_profile "un."
+;----------------------------------------------------
+!define NT_current_env 'HKCU "Environment"'
+!define NT_all_env     'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
+;====================================================
 ; AddToPath - Adds the given dir to the search path.
 ;        Input - head of the stack
 ;        Note - Win9x systems requires reboot
- 
+;====================================================
 Function AddToPath
-  Exch $0
-  Push $1
-  Push $2
-  Push $3
- 
-  # don't add if the path doesn't exist
-  IfFileExists "$0\*.*" "" AddToPath_done
- 
-  ReadEnvStr $1 PATH
-  Push "$1;"
-  Push "$0;"
-  Call StrStr
-  Pop $2
-  StrCmp $2 "" "" AddToPath_done
-  Push "$1;"
-  Push "$0\;"
-  Call StrStr
-  Pop $2
-  StrCmp $2 "" "" AddToPath_done
-  GetFullPathName /SHORT $3 $0
-  Push "$1;"
-  Push "$3;"
-  Call StrStr
-  Pop $2
-  StrCmp $2 "" "" AddToPath_done
-  Push "$1;"
-  Push "$3\;"
-  Call StrStr
-  Pop $2
-  StrCmp $2 "" "" AddToPath_done
- 
-  Call IsNT
-  Pop $1
-  StrCmp $1 1 AddToPath_NT
-    ; Not on NT
-    StrCpy $1 $WINDIR 2
-    FileOpen $1 "$1\autoexec.bat" a
-    FileSeek $1 -1 END
-    FileReadByte $1 $2
-    IntCmp $2 26 0 +2 +2 # DOS EOF
-      FileSeek $1 -1 END # write over EOF
-    FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
-    FileClose $1
-    SetRebootFlag true
-    Goto AddToPath_done
+   Exch $0
+   Push $1
+   Push $2
+  
+   Call IsNT
+   Pop $1
+   StrCmp $1 1 AddToPath_NT
+      ; Not on NT
+      StrCpy $1 $WINDIR 2
+      FileOpen $1 "$1\autoexec.bat" a
+      FileSeek $1 0 END
+      GetFullPathName /SHORT $0 $0
+      FileWrite $1 "$\r$\n\
+$\r$\n\
+SET PATH=%PATH%;$0$\r$\n\
+$\r$\n\
+"
+      FileClose $1
+      Goto AddToPath_done
  
-  AddToPath_NT:
-    MessageBox MB_OK 'Add to path "$0"'
-    ReadRegStr $1 SHCTX "Environment" "PATH"
-    StrCpy $2 $1 1 -1 # copy last char
-    StrCmp $2 ";" 0 +2 # if last char == ;
-      StrCpy $1 $1 -1 # remove last char
-    StrCmp $1 "" AddToPath_NTdoIt
-      StrCpy $0 "$1;$0"
-    AddToPath_NTdoIt:
-      WriteRegExpandStr SHCTX "Environment" "PATH" $0
-      SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+   AddToPath_NT:
+      Push $4
+      Call select_NT_profile
+      Pop  $4
  
-  AddToPath_done:
-    Pop $3
-    Pop $2
-    Pop $1
-    Pop $0
+      AddToPath_NT_selection_done:
+      StrCmp $4 "current" read_path_NT_current
+         ReadRegStr $1 ${NT_all_env} "PATH"
+         Goto read_path_NT_resume
+      read_path_NT_current:
+         ReadRegStr $1 ${NT_current_env} "PATH"
+      read_path_NT_resume:
+      StrCmp $1 "" AddToPath_NTdoIt
+         StrCpy $2 "$0;$1"
+         Goto AddToPath_NTdoIt
+      AddToPath_NTdoIt:
+         StrCmp $4 "current" write_path_NT_current
+            ClearErrors
+            WriteRegExpandStr ${NT_all_env} "PATH" $2
+            IfErrors 0 write_path_NT_resume
+            MessageBox MB_YESNO|MB_ICONQUESTION "The path could not be set for all users$\n\
+$\n\
+Should I try for the current user?" \
+               IDNO write_path_NT_failed
+            ; change selection
+            StrCpy $4 "current"
+            Goto AddToPath_NT_selection_done
+         write_path_NT_current:
+            ClearErrors
+            WriteRegExpandStr ${NT_current_env} "PATH" $2
+            IfErrors 0 write_path_NT_resume
+            MessageBox MB_OK|MB_ICONINFORMATION "The path could not be set for the current user."
+            Goto write_path_NT_failed
+         write_path_NT_resume:
+         SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+         DetailPrint "added path for user ($4), $0"
+         write_path_NT_failed:
+      
+      Pop $4
+   AddToPath_done:
+   Pop $2
+   Pop $1
+   Pop $0
 FunctionEnd
  
+;====================================================
 ; RemoveFromPath - Remove a given dir from the path
 ;     Input: head of the stack
- 
+;====================================================
 Function un.RemoveFromPath
-  Exch $0
-  Push $1
-  Push $2
-  Push $3
-  Push $4
-  Push $5
-  Push $6
- 
-  IntFmt $6 "%c" 26 # DOS EOF
- 
-  Call un.IsNT
-  Pop $1
-  StrCmp $1 1 unRemoveFromPath_NT
-    ; Not on NT
-    StrCpy $1 $WINDIR 2
-    FileOpen $1 "$1\autoexec.bat" r
-    GetTempFileName $4
-    FileOpen $2 $4 w
-    GetFullPathName /SHORT $0 $0
-    StrCpy $0 "SET PATH=%PATH%;$0"
-    Goto unRemoveFromPath_dosLoop
- 
-    unRemoveFromPath_dosLoop:
-      FileRead $1 $3
-      StrCpy $5 $3 1 -1 # read last char
-      StrCmp $5 $6 0 +2 # if DOS EOF
-        StrCpy $3 $3 -1 # remove DOS EOF so we can compare
-      StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
-      StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
-      StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
-      StrCmp $3 "" unRemoveFromPath_dosLoopEnd
-      FileWrite $2 $3
+   Exch $0
+   Push $1
+   Push $2
+   Push $3
+   Push $4
+   
+   Call un.IsNT
+   Pop $1
+   StrCmp $1 1 unRemoveFromPath_NT
+      ; Not on NT
+      StrCpy $1 $WINDIR 2
+      FileOpen $1 "$1\autoexec.bat" r
+      GetTempFileName $4
+      FileOpen $2 $4 w
+      GetFullPathName /SHORT $0 $0
+      StrCpy $0 "SET PATH=%PATH%;$0"
+      SetRebootFlag true
       Goto unRemoveFromPath_dosLoop
-      unRemoveFromPath_dosLoopRemoveLine:
-        SetRebootFlag true
-        Goto unRemoveFromPath_dosLoop
+     
+      unRemoveFromPath_dosLoop:
+         FileRead $1 $3
+         StrCmp $3 "$0$$\r$\n\
+$\r$\n\
+" unRemoveFromPath_dosLoop
+         StrCmp $3 "$0$\r$\n\
+" unRemoveFromPath_dosLoop
+         StrCmp $3 "$0" unRemoveFromPath_dosLoop
+         StrCmp $3 "" unRemoveFromPath_dosLoopEnd
+         FileWrite $2 $3
+         Goto unRemoveFromPath_dosLoop
  
-    unRemoveFromPath_dosLoopEnd:
-      FileClose $2
-      FileClose $1
-      StrCpy $1 $WINDIR 2
-      Delete "$1\autoexec.bat"
-      CopyFiles /SILENT $4 "$1\autoexec.bat"
-      Delete $4
-      Goto unRemoveFromPath_done
+      unRemoveFromPath_dosLoopEnd:
+         FileClose $2
+         FileClose $1
+         StrCpy $1 $WINDIR 2
+         Delete "$1\autoexec.bat"
+         CopyFiles /SILENT $4 "$1\autoexec.bat"
+         Delete $4
+         Goto unRemoveFromPath_done
  
-  unRemoveFromPath_NT:
-    MessageBox MB_OK 'Remove from path "$0"'
-    ReadRegStr $1 SHCTX "Environment" "PATH"
-    StrCpy $5 $1 1 -1 # copy last char
-    StrCmp $5 ";" +2 # if last char != ;
-      StrCpy $1 "$1;" # append ;
-    Push $1
-    Push "$0;"
-    Call un.StrStr ; Find `$0;` in $1
-    Pop $2 ; pos of our dir
-    StrCmp $2 "" unRemoveFromPath_done
-      ; else, it is in path
-      # $0 - path to add
-      # $1 - path var
-      StrLen $3 "$0;"
-      StrLen $4 $2
-      StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
-      StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
-      StrCpy $3 $5$6
+   unRemoveFromPath_NT:
+      StrLen $2 $0
+      Call un.select_NT_profile
+      Pop  $4
  
-      StrCpy $5 $3 1 -1 # copy last char
-      StrCmp $5 ";" 0 +2 # if last char == ;
-        StrCpy $3 $3 -1 # remove last char
+      StrCmp $4 "current" un_read_path_NT_current
+         ReadRegStr $1 ${NT_all_env} "PATH"
+         Goto un_read_path_NT_resume
+      un_read_path_NT_current:
+         ReadRegStr $1 ${NT_current_env} "PATH"
+      un_read_path_NT_resume:
  
-      WriteRegExpandStr SHCTX "Environment" "PATH" $3
-      SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+      Push $1
+      Push $0
+      Call un.StrStr ; Find $0 in $1
+      Pop $0 ; pos of our dir
+      IntCmp $0 -1 unRemoveFromPath_done
+         ; else, it is in path
+         StrCpy $3 $1 $0 ; $3 now has the part of the path before our dir
+         IntOp $2 $2 + $0 ; $2 now contains the pos after our dir in the path (';')
+         IntOp $2 $2 + 1 ; $2 now containts the pos after our dir and the semicolon.
+         StrLen $0 $1
+         StrCpy $1 $1 $0 $2
+         StrCpy $3 "$3$1"
  
-  unRemoveFromPath_done:
-    Pop $6
-    Pop $5
-    Pop $4
-    Pop $3
-    Pop $2
-    Pop $1
-    Pop $0
+         StrCmp $4 "current" un_write_path_NT_current
+            WriteRegExpandStr ${NT_all_env} "PATH" $3
+            Goto un_write_path_NT_resume
+         un_write_path_NT_current:
+            WriteRegExpandStr ${NT_current_env} "PATH" $3
+         un_write_path_NT_resume:
+         SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
+   unRemoveFromPath_done:
+   Pop $4
+   Pop $3
+   Pop $2
+   Pop $1
+   Pop $0
 FunctionEnd
- 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Uninstall sutff
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 ###########################################
 #            Utility Functions            #
 ###########################################
  
+;====================================================
+; IsNT - Returns 1 if the current system is NT, 0
+;        otherwise.
+;     Output: head of the stack
+;====================================================
 ; IsNT
 ; no input
 ; output, top of the stack = 1 if NT or 0 if not