154 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			NSIS
		
	
	
	
	
	
		
		
			
		
	
	
			154 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			NSIS
		
	
	
	
	
	
| 
								 | 
							
								!include "WinMessages.nsh"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; see https://support.microsoft.com/en-us/kb/104011
							 | 
						||
| 
								 | 
							
								!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
							 | 
						||
| 
								 | 
							
								; HKEY_LOCAL_MACHINE = 0x80000002
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; AddToPath - Appends dir to PATH
							 | 
						||
| 
								 | 
							
								;   (does not work on Win9x/ME)
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								; Usage:
							 | 
						||
| 
								 | 
							
								;   Push "dir"
							 | 
						||
| 
								 | 
							
								;   Call AddToPath
							 | 
						||
| 
								 | 
							
								Function AddToPath
							 | 
						||
| 
								 | 
							
								  Exch $0
							 | 
						||
| 
								 | 
							
								  Push $1
							 | 
						||
| 
								 | 
							
								  Push $2
							 | 
						||
| 
								 | 
							
								  Push $3
							 | 
						||
| 
								 | 
							
								  Push $4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; NSIS ReadRegStr returns empty string on string overflow
							 | 
						||
| 
								 | 
							
								  ; Native calls are used here to check actual length of PATH
							 | 
						||
| 
								 | 
							
								  ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3)
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4"
							 | 
						||
| 
								 | 
							
								  IntCmp $4 0 0 done done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
							 | 
						||
| 
								 | 
							
								  ; RegCloseKey($3)
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegCloseKey(i $3)"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
							 | 
						||
| 
								 | 
							
								    DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
							 | 
						||
| 
								 | 
							
								    MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
							 | 
						||
| 
								 | 
							
								    Goto done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  IntCmp $4 0 +5 ; $4 != NO_ERROR
							 | 
						||
| 
								 | 
							
								    IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
							 | 
						||
| 
								 | 
							
								      DetailPrint "AddToPath: unexpected error code $4"
							 | 
						||
| 
								 | 
							
								      Goto done
							 | 
						||
| 
								 | 
							
								    StrCpy $1 ""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; Check if already in PATH
							 | 
						||
| 
								 | 
							
								  Push "$1;"
							 | 
						||
| 
								 | 
							
								  Push "$0;"
							 | 
						||
| 
								 | 
							
								  Call StrStr
							 | 
						||
| 
								 | 
							
								  Pop $2
							 | 
						||
| 
								 | 
							
								  StrCmp $2 "" 0 done
							 | 
						||
| 
								 | 
							
								  Push "$1;"
							 | 
						||
| 
								 | 
							
								  Push "$0\;"
							 | 
						||
| 
								 | 
							
								  Call StrStr
							 | 
						||
| 
								 | 
							
								  Pop $2
							 | 
						||
| 
								 | 
							
								  StrCmp $2 "" 0 done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; Prevent NSIS string overflow
							 | 
						||
| 
								 | 
							
								  StrLen $2 $0
							 | 
						||
| 
								 | 
							
								  StrLen $3 $1
							 | 
						||
| 
								 | 
							
								  IntOp $2 $2 + $3
							 | 
						||
| 
								 | 
							
								  IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
							 | 
						||
| 
								 | 
							
								  IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
							 | 
						||
| 
								 | 
							
								    DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
							 | 
						||
| 
								 | 
							
								    MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}."
							 | 
						||
| 
								 | 
							
								    Goto done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; Append dir to PATH
							 | 
						||
| 
								 | 
							
								  DetailPrint "Add to PATH: $0"
							 | 
						||
| 
								 | 
							
								  StrCpy $2 $1 1 -1
							 | 
						||
| 
								 | 
							
								  StrCmp $2 ";" 0 +2
							 | 
						||
| 
								 | 
							
								    StrCpy $1 $1 -1 ; remove trailing ';'
							 | 
						||
| 
								 | 
							
								  StrCmp $1 "" +2   ; no leading ';'
							 | 
						||
| 
								 | 
							
								    StrCpy $0 "$1;$0"
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  WriteRegExpandStr ${Environ} "PATH" $0
							 | 
						||
| 
								 | 
							
								  SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								  Pop $4
							 | 
						||
| 
								 | 
							
								  Pop $3
							 | 
						||
| 
								 | 
							
								  Pop $2
							 | 
						||
| 
								 | 
							
								  Pop $1
							 | 
						||
| 
								 | 
							
								  Pop $0
							 | 
						||
| 
								 | 
							
								FunctionEnd
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								; RemoveFromPath - Removes dir from PATH
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								; Usage:
							 | 
						||
| 
								 | 
							
								;   Push "dir"
							 | 
						||
| 
								 | 
							
								;   Call RemoveFromPath
							 | 
						||
| 
								 | 
							
								Function un.RemoveFromPath
							 | 
						||
| 
								 | 
							
								  Exch $0
							 | 
						||
| 
								 | 
							
								  Push $1
							 | 
						||
| 
								 | 
							
								  Push $2
							 | 
						||
| 
								 | 
							
								  Push $3
							 | 
						||
| 
								 | 
							
								  Push $4
							 | 
						||
| 
								 | 
							
								  Push $5
							 | 
						||
| 
								 | 
							
								  Push $6
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; NSIS ReadRegStr returns empty string on string overflow
							 | 
						||
| 
								 | 
							
								  ; Native calls are used here to check actual length of PATH
							 | 
						||
| 
								 | 
							
								  ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3)
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4"
							 | 
						||
| 
								 | 
							
								  IntCmp $4 0 0 done done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2))
							 | 
						||
| 
								 | 
							
								  ; RegCloseKey($3)
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
							 | 
						||
| 
								 | 
							
								  System::Call "advapi32::RegCloseKey(i $3)"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
							 | 
						||
| 
								 | 
							
								    DetailPrint "RemoveFromPath: original length $2 > ${NSIS_MAX_STRLEN}"
							 | 
						||
| 
								 | 
							
								    MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
							 | 
						||
| 
								 | 
							
								    Goto done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  IntCmp $4 0 +5 ; $4 != NO_ERROR
							 | 
						||
| 
								 | 
							
								    IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
							 | 
						||
| 
								 | 
							
								      DetailPrint "RemoveFromPath: unexpected error code $4"
							 | 
						||
| 
								 | 
							
								      Goto done
							 | 
						||
| 
								 | 
							
								    StrCpy $1 ""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ; length < ${NSIS_MAX_STRLEN} -> ReadRegStr can be used
							 | 
						||
| 
								 | 
							
								  ReadRegStr $1 ${Environ} "PATH"
							 | 
						||
| 
								 | 
							
								  StrCpy $5 $1 1 -1
							 | 
						||
| 
								 | 
							
								  StrCmp $5 ";" +2
							 | 
						||
| 
								 | 
							
								  StrCpy $1 "$1;" ; ensure trailing ';'
							 | 
						||
| 
								 | 
							
								  Push $1
							 | 
						||
| 
								 | 
							
								  Push "$0;"
							 | 
						||
| 
								 | 
							
								  Call un.StrStr
							 | 
						||
| 
								 | 
							
								  Pop $2 ; pos of our dir
							 | 
						||
| 
								 | 
							
								  StrCmp $2 "" done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  DetailPrint "Remove from PATH: $0"
							 | 
						||
| 
								 | 
							
								  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"
							 | 
						||
| 
								 | 
							
								  StrCpy $5 $3 1 -1
							 | 
						||
| 
								 | 
							
								  StrCmp $5 ";" 0 +2
							 | 
						||
| 
								 | 
							
								    StrCpy $3 $3 -1 ; remove trailing ';'
							 | 
						||
| 
								 | 
							
								  WriteRegExpandStr ${Environ} "PATH" $3
							 | 
						||
| 
								 | 
							
								  SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								done:
							 | 
						||
| 
								 | 
							
								  Pop $6
							 | 
						||
| 
								 | 
							
								  Pop $5
							 | 
						||
| 
								 | 
							
								  Pop $4
							 | 
						||
| 
								 | 
							
								  Pop $3
							 | 
						||
| 
								 | 
							
								  Pop $2
							 | 
						||
| 
								 | 
							
								  Pop $1
							 | 
						||
| 
								 | 
							
								  Pop $0
							 | 
						||
| 
								 | 
							
								FunctionEnd
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								
							 |