NSIS has a default MAX_STR_LEN of 1024. If $ENV{PATH} is longer
the returned string is truncated to an empty string. Its then not
possible to distinguis between the variable not set or too long.
As a result the variable is set with the location where geth and/or
dev tools are installed. This may override any previous set values.
		
	
		
			
				
	
	
		
			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
 | |
|  
 | |
| 
 |