143 lines
3.3 KiB
NSIS
143 lines
3.3 KiB
NSIS
; EnvVarUpdate.nsh
|
|
; Adds/removes a value from a Windows environment variable (PATH-style, semicolon-delimited)
|
|
; Usage:
|
|
; ${EnvVarUpdate} $0 "PATH" "A" "HKLM" "$INSTDIR" ; append
|
|
; ${UnEnvVarUpdate} $0 "PATH" "HKLM" "$INSTDIR" ; remove
|
|
|
|
!ifndef ENVVARUPDATE_NSH
|
|
!define ENVVARUPDATE_NSH
|
|
|
|
!include "LogicLib.nsh"
|
|
!include "WinMessages.nsh"
|
|
|
|
; --------------------------------------------------------------------------
|
|
; Macro: _EnvVarUpdate
|
|
; Action: "A" = Append, "P" = Prepend, "R" = Remove
|
|
; --------------------------------------------------------------------------
|
|
!macro _EnvVarUpdate OUTVAR EnvVarName Action RegLoc PathString
|
|
|
|
Push $0
|
|
Push $1
|
|
Push $2
|
|
Push $3
|
|
Push $4
|
|
Push $5
|
|
|
|
; Read current value
|
|
ReadRegStr $1 ${RegLoc} \
|
|
"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" \
|
|
"${EnvVarName}"
|
|
|
|
; Strip trailing semicolon
|
|
StrCpy $5 $1 1 -1
|
|
${If} $5 == ";"
|
|
StrCpy $1 $1 -1
|
|
${EndIf}
|
|
|
|
; Check if PathString already exists
|
|
Push "${PathString}"
|
|
Push $1
|
|
Call _EnvVarUpdateStrStr
|
|
Pop $2 ; $2 = position, or "" if not found
|
|
|
|
${If} "${Action}" == "A"
|
|
${If} $2 == ""
|
|
${If} $1 == ""
|
|
StrCpy $3 "${PathString}"
|
|
${Else}
|
|
StrCpy $3 "$1;${PathString}"
|
|
${EndIf}
|
|
WriteRegExpandStr ${RegLoc} \
|
|
"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" \
|
|
"${EnvVarName}" "$3"
|
|
${EndIf}
|
|
${ElseIf} "${Action}" == "P"
|
|
${If} $2 == ""
|
|
${If} $1 == ""
|
|
StrCpy $3 "${PathString}"
|
|
${Else}
|
|
StrCpy $3 "${PathString};$1"
|
|
${EndIf}
|
|
WriteRegExpandStr ${RegLoc} \
|
|
"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" \
|
|
"${EnvVarName}" "$3"
|
|
${EndIf}
|
|
${ElseIf} "${Action}" == "R"
|
|
${If} $2 != ""
|
|
; Remove entry
|
|
StrLen $4 "${PathString}"
|
|
StrCpy $0 $1 $2 ; everything before the match
|
|
IntOp $4 $2 + $4 ; position after the match
|
|
StrCpy $5 $1 "" $4 ; everything after the match
|
|
; Strip leading/trailing semicolons from join point
|
|
StrCpy $4 $5 1
|
|
${If} $4 == ";"
|
|
StrCpy $5 $5 "" 1
|
|
${EndIf}
|
|
StrCpy $4 $0 1 -1
|
|
${If} $4 == ";"
|
|
StrCpy $0 $0 -1
|
|
${EndIf}
|
|
${If} $0 == ""
|
|
StrCpy $3 $5
|
|
${ElseIf} $5 == ""
|
|
StrCpy $3 $0
|
|
${Else}
|
|
StrCpy $3 "$0;$5"
|
|
${EndIf}
|
|
WriteRegExpandStr ${RegLoc} \
|
|
"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" \
|
|
"${EnvVarName}" "$3"
|
|
${EndIf}
|
|
${EndIf}
|
|
|
|
; Broadcast change to all windows
|
|
SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
|
|
|
Pop $5
|
|
Pop $4
|
|
Pop $3
|
|
Pop $2
|
|
Pop $1
|
|
Pop $0
|
|
|
|
!macroend
|
|
|
|
; Helper: find substring position (returns "" if not found)
|
|
Function _EnvVarUpdateStrStr
|
|
Exch $R0 ; haystack
|
|
Exch
|
|
Exch $R1 ; needle
|
|
Push $R2
|
|
Push $R3
|
|
Push $R4
|
|
Push $R5
|
|
StrLen $R3 $R1
|
|
StrLen $R4 $R0
|
|
IntOp $R4 $R4 - $R3
|
|
StrCpy $R2 0
|
|
loop:
|
|
IntCmp $R2 $R4 done done
|
|
StrCpy $R5 $R0 $R3 $R2
|
|
StrCmp $R5 $R1 found
|
|
IntOp $R2 $R2 + 1
|
|
Goto loop
|
|
found:
|
|
StrCpy $R0 $R2
|
|
Goto end
|
|
done:
|
|
StrCpy $R0 ""
|
|
end:
|
|
Pop $R5
|
|
Pop $R4
|
|
Pop $R3
|
|
Pop $R2
|
|
Pop $R1
|
|
Exch $R0
|
|
FunctionEnd
|
|
|
|
!define EnvVarUpdate `!insertmacro _EnvVarUpdate`
|
|
!define UnEnvVarUpdate `!insertmacro _EnvVarUpdate "" "${__LINE__}" "R"`
|
|
|
|
!endif ; ENVVARUPDATE_NSH
|