在Windows 7中使用NSIS设置环境variables

我想使用NSIS安装程序设置环境variables。 如果重要,我将在Windows 7上运行脚本。 谢谢!

我如何创建或更改环境变量

注意:以这种方式更改%path%是不安全的,如果它长于NSIS字符串长度,可能会损坏条目!

您可以创建一个Windows批处理文件,像安装其他文件一样将其打包,安装后将其解压到plugins目录并执行:

 File "/oname=$PluginsDir\appendvar.bat" "PathToScriptDir\appendvar.bat" nsExec::ExecToLog '"$SYSDIR\cmd.exe" /C "$PluginsDir\appendvar.bat" -g -all' Pop $R0 ; last error Delete "$PluginsDir\appendvar.bat" 

appendvar.bat脚本(某种全局和本地追加的通用实现):

 @echo off rem Drop last error level cd . rem Create local variable's stack setlocal set "?~nx0=%~nx0" rem script flags rem set variable in global registry for a current user set __FLAG_SET_GLOBAL_REGISTRY=0 rem Set variable in global registry for all users. rem Has no meaning if global flag has not used. set __FLAG_SET_GLOBAL_REGISTRY_ALL_USERS=0 rem If setting global variable, then do include changes for a local cmd.exe process environment (by default, it is excluded) rem Has no meaning if global flag has not used. set __FLAG_SET_LOCAL=0 rem Force append even if exist. set __FLAG_FORCE=0 :FLAGS_LOOP rem flags always at first set "__FLAG=%~1" if not "%__FLAG%" == "" ^ if not "%__FLAG:~0,1%" == "-" set "__FLAG=" if not "%__FLAG%" == "" ( if "%__FLAG%" == "-g" ( set __FLAG_SET_GLOBAL_REGISTRY=1 shift ) else if "%__FLAG%" == "-all" ( if %__FLAG_SET_GLOBAL_REGISTRY% NEQ 0 set __FLAG_SET_GLOBAL_REGISTRY_ALL_USERS=1 shift ) else if "%__FLAG%" == "-l" ( set __FLAG_SET_LOCAL=1 shift ) else if "%__FLAG%" == "-f" ( set __FLAG_FORCE=1 shift ) else ( echo.%?~nx0%: error: invalid flag: %__FLAG% exit /b -255 ) >&2 rem read until no flags goto FLAGS_LOOP ) if "%~1" == "" ( echo.%?~nx0%: error: variable name is not set. exit /b 1 ) set "__SEPARATOR=" if not "%~3" == "" set "__SEPARATOR=%~3" if "%__SEPARATOR%" == "" set "__SEPARATOR=;" set "__SEPARATOR=%__SEPARATOR:~0,1%" set "__NEW_VALUE=%~2" rem remove trailing separator character if not "%__NEW_VALUE%" == "" ( if "%__SEPARATOR%" == "%__NEW_VALUE:~-1%" ( set "__NEW_VALUE=%__NEW_VALUE:~0,-1%" ) ) rem remove trailing "\" character if not "%__NEW_VALUE%" == "" ( if "\" == "%__NEW_VALUE:~-1%" ( set "__NEW_VALUE=%__NEW_VALUE:~0,-1%" ) ) if "%__NEW_VALUE%" == "" ( if "%~2" == "" exit /b 0 rem the variable value is a separator character only exit /b 2 ) rem set local at least if %__FLAG_SET_GLOBAL_REGISTRY%%__FLAG_SET_LOCAL% EQU 0 set __FLAG_SET_LOCAL=1 if %__FLAG_SET_GLOBAL_REGISTRY% EQU 0 goto SET_GLOBAL_END rem global setup set "__VAR_VALUE=" if %__FLAG_SET_GLOBAL_REGISTRY_ALL_USERS% NEQ 0 ( set __FLAG_SET_GLOBAL_REGISTRY_WMIC_WHERE_EXP=where "Name='Path' and UserName='<SYSTEM>'" ) else ( set __FLAG_SET_GLOBAL_REGISTRY_WMIC_WHERE_EXP=where "Name='Path' and UserName!='<SYSTEM>'" ) for /F "usebackq eol= tokens=1,* delims==" %%i in (`wmic environment %__FLAG_SET_GLOBAL_REGISTRY_WMIC_WHERE_EXP% get VariableValue /VALUE 2^>NUL`) do if "%%i" == "VariableValue" set "__VAR_VALUE=%%j" if not "%__VAR_VALUE%" == "" ( if "%__SEPARATOR%" == "%__VAR_VALUE:~-1%" ( set "__VAR_VALUE=%__VAR_VALUE:~0,-1%" ) ) rem check on existance if %__FLAG_FORCE% NEQ 0 goto SET_GLOBAL_IMPL if "%__VAR_VALUE%" == "" goto SET_GLOBAL_IMPL set "__VAR_VALUE_TMP=%__SEPARATOR%%__VAR_VALUE%%__SEPARATOR%" call set "__VAR_VALUE_TMP_EXCLUDED=%%__VAR_VALUE_TMP:%__SEPARATOR%%__NEW_VALUE%%__SEPARATOR%=%%" if /i not "%__VAR_VALUE_TMP_EXCLUDED%" == "%__VAR_VALUE_TMP%" goto SET_GLOBAL_END :SET_GLOBAL_IMPL if not "%__VAR_VALUE%" == "" ( wmic environment %__FLAG_SET_GLOBAL_REGISTRY_WMIC_WHERE_EXP% set VariableValue="%__VAR_VALUE%%__SEPARATOR%%__NEW_VALUE%" ) else ( wmic environment %__FLAG_SET_GLOBAL_REGISTRY_WMIC_WHERE_EXP% set VariableValue="%__NEW_VALUE%" ) :SET_GLOBAL_END if %__FLAG_SET_LOCAL% EQU 0 exit /b rem local setup call set "__VAR_VALUE=%%%~1%%" if not "%__VAR_VALUE%" == "" ( if "%__SEPARATOR%" == "%__VAR_VALUE:~-1%" ( set "__VAR_VALUE=%__VAR_VALUE:~0,-1%" ) ) rem check on existance if %__FLAG_FORCE% NEQ 0 goto SET_LOCAL_IMPL if "%__VAR_VALUE%" == "" goto SET_LOCAL_IMPL set "__VAR_VALUE_TMP=%__SEPARATOR%%__VAR_VALUE%%__SEPARATOR%" call set "__VAR_VALUE_TMP_EXCLUDED=%%__VAR_VALUE_TMP:%__SEPARATOR%%__NEW_VALUE%%__SEPARATOR%=%%" if /i not "%__VAR_VALUE_TMP_EXCLUDED%" == "%__VAR_VALUE_TMP%" goto SET_LOCAL_END :SET_LOCAL_IMPL if not "%__VAR_VALUE%" == "" ( endlocal set "%~1=%__VAR_VALUE%%__SEPARATOR%%__NEW_VALUE%" ) else ( endlocal set "%~1=%__NEW_VALUE%" ) :SET_LOCAL_END exit /b 0 

你可以替换

 %__VAR_VALUE%%__SEPARATOR%%__NEW_VALUE% 

 %__NEW_VALUE%%__SEPARATOR%%__VAR_VALUE% 

如果想要预先设置一个变量值。

注意:脚本有问题:

  • 值与忽略大小写比较
  • 可以更新超过1024个字符(测试),但不超过4096个字符我认为(未测试)
  • 如果使用-g和-all标志,则cmd.exe进程必须以管理员权限运行。

更新RegAddPathToVar函数的最新版本在这里: https : RegAddPathToVar (完整的测试例子: https : RegAddPathToVar test_RegAddRemovePathGUI / main.nsi )

这是NSIS 3.0的完整且直接的实现示例。

包含3个文件。

build.bat – 建立脚本文件。

 @echo off set "MAKENSIS_EXE=makensis.exe" "%MAKENSIS_EXE%" /V4 "/Obuild.log" "/XOutFile '%~dp0test.exe'" "%~dp0main.nsi" echo.Return code: %ERRORLEVEL% pause 

编辑MAKENSIS_EXE变量到那里makensis可执行文件在您的系统上。

stack.nsi – 帮助函数文件。

 !define PushStack11 "!insertmacro PushStack11" !macro PushStack11 var0 var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 Push `${var0}` Push `${var1}` Push `${var2}` Push `${var3}` Push `${var4}` Push `${var5}` Push `${var6}` Push `${var7}` Push `${var8}` Push `${var9}` Push `${var10}` !macroend !define ExchStack4 "!insertmacro ExchStack4" !macro ExchStack4 var0 var1 var2 var3 Exch `${var3}` Exch 1 Exch `${var2}` Exch 1 Exch 2 Exch `${var1}` Exch 2 Exch 3 Exch `${var0}` Exch 3 !macroend !define PopStack15 "!insertmacro PopStack15" !macro PopStack15 var0 var1 var2 var3 var4 var5 var6 var7 var8 var9 var10 var11 var12 var13 var14 Pop `${var14}` Pop `${var13}` Pop `${var12}` Pop `${var11}` Pop `${var10}` Pop `${var9}` Pop `${var8}` Pop `${var7}` Pop `${var6}` Pop `${var5}` Pop `${var4}` Pop `${var3}` Pop `${var2}` Pop `${var1}` Pop `${var0}` !macroend 

main.nsi – 完整的NSIS实现示例。

 !include "nsDialogs.nsh" !include "WinCore.nsh" !include "LogicLib.nsh" !include "stack.nsi" RequestExecutionLevel admin ; for all users Page Custom Show Leave Var /GLOBAL DialogID Var /GLOBAL EditID Var /GLOBAL Edit Var /GLOBAL ButtonAppendID !define GotoIf "!insertmacro GotoIf" !macro GotoIf label exp ${If} ${exp} Goto `${label}` ${EndIf} !macroend !define RegGetKeyMap "!insertmacro RegGetKeyMap" !macro RegGetKeyMap var value ${Switch} ${value} ${Case} "HKCR" StrCpy ${var} ${HKEY_CLASSES_ROOT} ${Break} ${Case} "HKCU" StrCpy ${var} ${HKEY_CURRENT_USER} ${Break} ${Case} "HKLM" StrCpy ${var} ${HKEY_LOCAL_MACHINE} ${Break} ${Case} "HKU" StrCpy ${var} ${HKEY_USERS} ${Break} ${Case} "HKPD" StrCpy ${var} ${HKEY_PERFORMANCE_DATA} ${Break} ${Case} "HKDD" StrCpy ${var} ${HKEY_DYN_DATA} ${Break} ${Case} "HKCC" StrCpy ${var} ${HKEY_CURRENT_CONFIG} ${Break} ${Case} "HKEY_CLASSES_ROOT" StrCpy ${var} ${HKEY_CLASSES_ROOT} ${Break} ${Case} "HKEY_CURRENT_USER" StrCpy ${var} ${HKEY_CURRENT_USER} ${Break} ${Case} "HKEY_LOCAL_MACHINE" StrCpy ${var} ${HKEY_LOCAL_MACHINE} ${Break} ${Case} "HKEY_USERS" StrCpy ${var} ${HKEY_USERS} ${Break} ${Case} "HKEY_PERFORMANCE_DATA" StrCpy ${var} ${HKEY_PERFORMANCE_DATA} ${Break} ${Case} "HKEY_DYN_DATA" StrCpy ${var} ${HKEY_DYN_DATA} ${Break} ${Case} "HKEY_CURRENT_CONFIG" StrCpy ${var} ${HKEY_CURRENT_CONFIG} ${Break} ${Default} StrCpy ${var} ${HKEY_CURRENT_USER} ${Break} ${EndSwitch} !macroend ; Usage: ; All users: ; ${Push} "<path>" ; ${Push} "HKLM" ; ${Push} "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" ; ${Push} "<env_var>" ; Call RegAddPathToVar ; Current user only: ; ${Push} "<path>" ; ${Push} "HKCU" ; ${Push} "Environment" ; ${Push} "<env_var>" ; Call RegAddPathToVar !macro Func_RegAddPathToVar un !ifndef ${un}RegAddPathToVar_INCLUDED !define ${un}RegAddPathToVar_INCLUDED Function ${un}RegAddPathToVar ${ExchStack4} $R0 $R1 $R2 $R3 ${PushStack11} $R4 $R5 $R6 $R7 $R8 $R9 $0 $1 $2 $8 $9 ; WARNING: ; NSIS ReadRegStr returns empty string on string overflow, so native calls are used here: ; 1. To check actual length of <env_var>. ; 2. To process the PATH variable of any length long. ; The IDEAL algorithm for any length long PATH variable, where each subpath is not longer than ${NSIS_MAX_STRLEN}-${NSIS_CHAR_SIZE} bytes: ; 1. Init current string list if does not have any before or take as current has created after the previous algorithm run. ; 2. Read string of ${NSIS_MAX_STRLEN}-${NSIS_CHAR_SIZE} bytes length into the array of ${NSIS_MAX_STRLEN} bytes length from the input address, add NSIS_CHAR_SIZE nulls at the end. ; 3. Go to 20 if empty or nothing else except the ; characters in the array. ; 4. Truncate all in the array after the last ; character, where the ; character has found not under " character quoted string (see description in the 6). ; 5. Split strings in the array by the ; character if it has found not under " character quoted string into the list. ; 6. Move the last string from the list into the next repeat cycle list if it begins by the " character but not ends by the same character (not completely fitted into the limited to ${NSIS_MAX_STRLEN} bytes window). ; 7. Unquote all strings in the list and create the second list with flags marked where the quotes has removed. ; 8. Search for "$R0" or "$R0\" in the list, if found then raise a flag and leave the algorithm. ; 9. Move ${NSIS_MAX_STRLEN} byte window by the array current string length long multiple to NSIS_CHAR_SIZE value along the input address. ; 10. Repeat the algorithm. ; 20. Append path to the list. ; 21. Restore quotes for those strings in the first list what been quoted before by the second list. ; 22. Join first list by the separator into one string. ; The REAL algorithm for any length long PATH variable, where each subpath is not longer than ${NSIS_MAX_STRLEN}-${NSIS_CHAR_SIZE} bytes: ; 1. Read string from registry into dynamic buffer enough to store more characters: length of being searched string + length of separator + length of string to search + length of null character. ; 2. Copy string from the buffer to the second dynamic buffer enough to store more characters: length of separator + length of being searched string + length of separator + length of null character. ; 3. Prepend and append separator character to second buffer. ; 4. Try to find multiple instances of the string to search in the second buffer through the shlwapi::StrStrI, where search instances are: ; `<Separator><StringToSearch><Separator>' ; `<Separator><StringToSearch>\<Separator>' ; 5. If found any instance then leave the algorithm. ; 6. Append separator character to the first buffer if it does not ending by it. ; 7. Append the string to search to the first buffer. ; handles and pointers init StrCpy $R7 0 StrCpy $R9 0 StrCpy $0 0 StrCpy $1 0 StrCpy $2 0 ; keys map ${RegGetKeyMap} $R8 $R1 System::Call "advapi32::RegOpenKey(i R8, t R2, *i.R6) i.R4" ${If} $R4 <> 0 DetailPrint "RegAddPathToVar: advapi32::RegOpenKey error: code=$R4 hive=$\"$R8$\" key=$\"$R2$\"" MessageBox MB_OK "RegAddPathToVar: advapi32::RegOpenKey error: code=$R4 hive=$\"$R8$\" key=$\"$R2$\"" /SD IDOK Goto done ${EndIf} System::Call "advapi32::RegQueryValueEx(i R6, t R3, i 0, *i .r9, p 0, *i 0 R7) i.R4" ${If} $R4 <> 0 DetailPrint "RegAddPathToVar: advapi32::RegQueryValueEx (1) is failed, unexpected error code: code=$R4 length=$\"$R7$\"" MessageBox MB_OK "RegAddPathToVar: advapi32::RegQueryValueEx (1) is failed, unexpected error code: code=$R4 length=$\"$R7$\"" /SD IDOK Goto done ${EndIf} ; remove trailing "\" character from the string to search StrCpy $R5 $R0 "" -1 ${If} $R5 == "\" StrCpy $R0 $R0 -1 ${EndIf} StrLen $R8 $R0 ; first buffer: length of being searched string + length of separator + length of string to search + length of null character IntOp $R5 $R8 + 1 ; ";" IntOp $R5 $R5 * ${NSIS_CHAR_SIZE} IntOp $R5 $R5 + $R7 ; already in bytes including null character ; allocate first dynamic buffer System::Alloc $R5 Pop $0 ${If} $0 = 0 DetailPrint "RegAddPathToVar: System::Alloc (1) is failed: size=$R5" MessageBox MB_OK "RegAddPathToVar: System::Alloc (1) is failed: size=$R5" /SD IDOK Goto done ${EndIf} System::Call "advapi32::RegQueryValueEx(i R6, t R3, i 0, i 0, p r0, *i R5 R7) i.R4" ${If} $R4 <> 0 DetailPrint "RegAddPathToVar: advapi32::RegQueryValueEx (2) is failed, unexpected error: code=$R4 length=$\"$R7$\"" MessageBox MB_OK "RegAddPathToVar: advapi32::RegQueryValueEx (2) is failed, unexpected error: code=$R4 length=$\"$R7$\"" /SD IDOK Goto done ${EndIf} ; strip separator characters from the first buffer end ${If} $R7 > ${NSIS_CHAR_SIZE} ; excluding null character IntOp $R5 $R7 - ${NSIS_CHAR_SIZE} IntOp $R5 $R5 - ${NSIS_CHAR_SIZE} IntOp $R9 $0 + $R5 strip_loop1: System::Call "*$R9(&t1 .r8)" ${If} $8 == ";" System::Call "*$R9(&t1 '')" ; null character IntOp $R7 $R7 - ${NSIS_CHAR_SIZE} ${If} $R9 >= ${NSIS_CHAR_SIZE} IntOp $R9 $R9 - ${NSIS_CHAR_SIZE} Goto strip_loop1 ${EndIf} ${EndIf} ${EndIf} ; second buffer: length of separator + length of being searched string + length of separator + length of null character IntOp $R5 2 * ${NSIS_CHAR_SIZE} ; 2 x ";" IntOp $R5 $R5 + $R7 ; already in bytes including null character ; allocate second dynamic buffer System::Alloc $R5 Pop $1 ${If} $1 = 0 DetailPrint "RegAddPathToVar: System::Alloc (2) is failed: size=$R5" MessageBox MB_OK "RegAddPathToVar: System::Alloc (2) is failed: size=$R5" /SD IDOK Goto done ${EndIf} System::Call "*$1(&t1 ';')" IntOp $R9 $1 + ${NSIS_CHAR_SIZE} System::Call "kernel32::lstrcpyn(p R9, p r0, i R7) p.R4" ${If} $R4 = 0 DetailPrint "RegAddPathToVar: kernel32::lstrcpyn (1) is failed" MessageBox MB_OK "RegAddPathToVar: kernel32::lstrcpyn (1) is failed" /SD IDOK Goto done ${EndIf} IntOp $R9 $R9 + $R7 IntOp $R9 $R9 - ${NSIS_CHAR_SIZE} ; exclude last null character System::Call "*$R9(&t1 ';')" IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} System::Call "*$R9(&t1 '')" ; null character ; buffer for the string to search IntOp $R5 0 + 4 ; 2 x ";" + "\" + length of null character IntOp $R5 $R5 + $R8 ; excluding null character IntOp $R5 $R5 * ${NSIS_CHAR_SIZE} System::Alloc $R5 Pop $2 ${If} $2 = 0 DetailPrint "RegAddPathToVar: System::Alloc (3) is failed: size=$R5" MessageBox MB_OK "RegAddPathToVar: System::Alloc (3) is failed: size=$R5" /SD IDOK Goto done ${EndIf} ; convert R8 (length of R0) to bytes IntOp $R8 $R8 * ${NSIS_CHAR_SIZE} ; `<Separator><StringToSearch><Separator>' System::Call "*$2(&t1 ';')" IntOp $R9 $2 + ${NSIS_CHAR_SIZE} System::Call "kernel32::lstrcpy(p R9, t R0) p.R4" ${If} $R4 = 0 DetailPrint "RegAddPathToVar: kernel32::lstrcpy (2) is failed" MessageBox MB_OK "RegAddPathToVar: kernel32::lstrcpy (2) is failed" /SD IDOK Goto done ${EndIf} IntOp $R9 $R9 + $R8 ; length does not include the last null character System::Call "*$R9(&t1 ';')" IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} System::Call "*$R9(&t1 '')" ; null character System::Call "shlwapi::StrStrI(p r1, p r2) p.R4" ${GotoIf} done "$R4 <> 0" ; `<Separator><StringToSearch>\<Separator>' System::Call "*$2(&t1 ';')" IntOp $R9 $2 + ${NSIS_CHAR_SIZE} IntOp $R9 $R9 + $R8 System::Call "*$R9(&t1 '\')" IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} System::Call "*$R9(&t1 ';')" IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} System::Call "*$R9(&t1 '')" ; null character System::Call "shlwapi::StrStrI(p r1, p r2) p.R4" ${GotoIf} done "$R4 <> 0" ; append to the first buffer IntOp $R9 0 + $0 ${If} $R7 > ${NSIS_CHAR_SIZE} IntOp $R9 $R9 + $R7 IntOp $R9 $R9 - ${NSIS_CHAR_SIZE} ; exclude last null character System::Call "*$R9(&t1 ';')" IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} ${EndIf} System::Call "kernel32::lstrcpy(p R9, t R0) p.R4" ${If} $R4 = 0 DetailPrint "RegAddPathToVar: kernel32::lstrcpy (3) is failed" MessageBox MB_OK "RegAddPathToVar: kernel32::lstrcpy (3) is failed" /SD IDOK Goto done ${EndIf} IntOp $R9 $R9 + $R8 ; length does not include the last null character System::Call "*$R9(&t1 '')" ; null character IntOp $R9 $R9 + ${NSIS_CHAR_SIZE} IntOp $R5 $R9 - $0 System::Call "advapi32::RegSetValueEx(i R6, t R3, i 0, i r9, p r0, i R5) i.R4" ${If} $R4 <> 0 DetailPrint "RegAddPathToVar: advapi32::RegSetValueEx (1) is failed" MessageBox MB_OK "RegAddPathToVar: advapi32::RegSetValueEx (1) is failed" /SD IDOK Goto done ${EndIf} ; broadcast global event SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 done: System::Call "advapi32::RegCloseKey(i $R6)" ${If} $0 <> 0 System::Free $0 ${EndIf} ${If} $1 <> 0 System::Free $1 ${EndIf} ${If} $2 <> 0 System::Free $2 ${EndIf} ${PopStack15} $R0 $R1 $R2 $R3 $R4 $R5 $R6 $R7 $R8 $R9 $0 $1 $2 $8 $9 FunctionEnd !endif !macroend !define Call_RegAddPathToVar "!insertmacro Call_RegAddPathToVar" !macro Call_RegAddPathToVar prefix path hkey hkey_path env_var Push `${path}` Push `${hkey}` Push `${hkey_path}` Push `${env_var}` Call ${prefix}RegAddPathToVar !macroend !define RegAddPathToVar "!insertmacro RegAddPathToVar" !macro RegAddPathToVar !insertmacro Func_RegAddPathToVar "" !undef RegAddPathToVar !define RegAddPathToVar "${Call_RegAddPathToVar} ''" !macroend !define un.RegAddPathToVar "!insertmacro un.RegAddPathToVar" !macro un.RegAddPathToVar !insertmacro Func_RegAddPathToVar "un." !undef un.RegAddPathToVar !define un.RegAddPathToVar "${Call_RegAddPathToVar} 'un.'" !macroend ; include for install only ${RegAddPathToVar} Function Show nsDialogs::Create 1018 Pop $DialogID ${NSD_CreateText} 0 16u 80% 14u "C:\MyPath\bin" Pop $EditID ${NSD_OnChange} $EditID WndProc ${NSD_CreateButton} 80% 16u 20% 14u "Append" Pop $ButtonAppendID ${NSD_OnClick} $ButtonAppendID WndProc StrCpy $R0 -1 Call Update nsDialogs::Show FunctionEnd Function Leave FunctionEnd Function WndProc System::Store SR0 Call Update System::Store L FunctionEnd Function Update ; read values ${If} $R0 = $EditID ${OrIf} $R0 = -1 ${NSD_GetText} $EditID $Edit ${EndIf} ${If} $R0 = $ButtonAppendID ${If} $Edit != "" #${RegAddPathToVar} "$Edit" HKCU "Environment" PATH ; for current user ${RegAddPathToVar} "$Edit" HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" PATH ; for all users ${EndIf} ${EndIf} FunctionEnd Section -Hidden SectionEnd