123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- !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
-
|