!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