NSIS操作系统环境变量
手头有个项目需要修改PATH变量
需要!include "EnvVarUpdate.nsh"
以下是NSIS脚本代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ; Script generated by the HM NIS Edit Script Wizard. !include "StrFunc.nsh" ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Setup_Wintech" !define PRODUCT_VERSION "2.0" !define PRODUCT_PUBLISHER "Wintech Digital Systems Technology Corp." !define PRODUCT_WEB_SITE "http://www.wintechdigital.com" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\makensis.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !define INSTALL_DIR_FILENAME "Wintech" ; MUI 1.67 compatible - - - - - - !include "MUI.nsh" !include "LogicLib.nsh" !include "x64.nsh" !include "EnvVarUpdate.nsh" ; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\Wintech.ico" !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\Wintech.ico" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page ;!insertmacro MUI_PAGE_LICENSE "${NSISDIR}\License.txt" ; Directory page !insertmacro MUI_PAGE_DIRECTORY ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_RUN "$INSTDIR\bin\wlp_exe_gui.exe" !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" !echo "Testing" ; MUI end - - - - - - RequestExecutionLevel admin Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "dlf_setup.exe" InstallDir "$PROGRAMFILES\${INSTALL_DIR_FILENAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" ShowInstDetails show ShowUnInstDetails show Section "MainSection" SEC01 ${EnvVarUpdate} $ 0 "PATH" "A" "HKLM" "$INSTDIR\bin" ; appends to the system path SetOutPath "$INSTDIR" SetOverwrite ifnewer File "${NSISDIR}\makensis.exe" CreateDirectory "$INSTDIR" CreateShortCut "$SMPROGRAMS\${INSTALL_DIR_FILENAME}\${INSTALL_DIR_FILENAME}.lnk" "$INSTDIR\makensis.exe" CreateShortCut "$DESKTOP\${INSTALL_DIR_FILENAME}.lnk" "$INSTDIR\makensis.exe" File "${NSISDIR}\License.txt" File / r "setup\*" ;Detect windows is 32bit or 64bit ${If} ${RunningX64} ; 64bit bits go here Exec '"$INSTDIR\bin\driver\win7\Psexec.exe" -i -d -s "$INSTDIR\bin\driver\win7\install_wdf_driver.exe"' ; - i - d - s "$INSTDIR\bin\Driver\win7install_wdf_driver.exe" ' ;Exec "$INSTDIR\bin\notepad2.exe" ExecWait "$INSTDIR\bin\vs2010sp1vcredist.exe" ${Else} ; 32bit bits go here Exec '"$INSTDIR\bin\driver\win7\Psexec.exe" -i -d -s "$INSTDIR\bin\driver\win7\install_wdf_driver.exe"' ExecWait '"$INSTDIR\bin\vs2010sp1vcredist.exe"' ${EndIf} SectionEnd Section - AdditionalIcons WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateShortCut "$SMPROGRAMS\MyScript\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\MyScript\Uninstall.lnk" "$INSTDIR\uninst.exe" SectionEnd Section - Post WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" " " " $INSTDIR\makensis.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\makensis.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从你的计算机移除。" FunctionEnd Function un.onInit MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "你确实要完全移除 $(^Name) ,其及所有的组件?" IDYES + 2 Abort FunctionEnd Section Uninstall Delete "$INSTDIR\${PRODUCT_NAME}.url" Delete "$INSTDIR\uninst.exe" Delete "$INSTDIR\setup" Delete "$INSTDIR\License.txt" Delete "$INSTDIR\makensis.exe" Delete "$SMPROGRAMS\${INSTALL_DIR_FILENAME}\Uninstall.lnk" Delete "$SMPROGRAMS\${INSTALL_DIR_FILENAME}\Website.lnk" Delete "$DESKTOP\${INSTALL_DIR_FILENAME}.lnk" Delete "$SMPROGRAMS\${INSTALL_DIR_FILENAME}\${INSTALL_DIR_FILENAME}.lnk" RMDir "$SMPROGRAMS\${INSTALL_DIR_FILENAME}" RMDir "$INSTDIR" DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SetAutoClose true SectionEnd |
以下时EnvVarUpdate.nsh的代码,需要拷贝到NSIS的include路径下面才能用:

1 /** 2 * EnvVarUpdate.nsh 3 * : Environmental Variables: append, prepend, and remove entries 4 * 5 * WARNING: If you use StrFunc.nsh header then include it before this file 6 * with all required definitions. This is to avoid conflicts 7 * 8 * Usage: 9 * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" 10 * 11 * Credits: 12 * Version 1.0 13 * * Cal Turney (turnec2) 14 * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this 15 * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, 16 * WriteEnvStr, and un.DeleteEnvStr 17 * * Diego Pedroso (deguix) for StrTok 18 * * Kevin English (kenglish_hi) for StrContains 19 * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry 20 * (dandaman32) for StrReplace 21 * 22 * Version 1.1 (compatibility with StrFunc.nsh) 23 * * techtonik 24 * 25 * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries 26 * 27 */ 28 29 30 !ifndef ENVVARUPDATE_FUNCTION 31 !define ENVVARUPDATE_FUNCTION 32 !verbose push 33 !verbose 3 34 !include "LogicLib.nsh" 35 !include "WinMessages.NSH" 36 !include "StrFunc.nsh" 37 38 ; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- 39 !macro _IncludeStrFunction StrFuncName 40 !ifndef ${StrFuncName}_INCLUDED 41 ${${StrFuncName}} 42 !endif 43 !ifndef Un${StrFuncName}_INCLUDED 44 ${Un${StrFuncName}} 45 !endif 46 !define un.${StrFuncName} "${Un${StrFuncName}}" 47 !macroend 48 49 !insertmacro _IncludeStrFunction StrTok 50 !insertmacro _IncludeStrFunction StrStr 51 !insertmacro _IncludeStrFunction StrRep 52 53 ; ---------------------------------- Macro Definitions ---------------------------------------- 54 !macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString 55 Push "${EnvVarName}" 56 Push "${Action}" 57 Push "${RegLoc}" 58 Push "${PathString}" 59 Call EnvVarUpdate 60 Pop "${ResultVar}" 61 !macroend 62 !define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' 63 64 !macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString 65 Push "${EnvVarName}" 66 Push "${Action}" 67 Push "${RegLoc}" 68 Push "${PathString}" 69 Call un.EnvVarUpdate 70 Pop "${ResultVar}" 71 !macroend 72 !define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' 73 ; ---------------------------------- Macro Definitions end------------------------------------- 74 75 ;----------------------------------- EnvVarUpdate start---------------------------------------- 76 !define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' 77 !define hkcu_current_user 'HKCU "Environment"' 78 79 !macro EnvVarUpdate UN 80 81 Function ${UN}EnvVarUpdate 82 83 Push $0 84 Exch 4 85 Exch $1 86 Exch 3 87 Exch $2 88 Exch 2 89 Exch $3 90 Exch 91 Exch $4 92 Push $5 93 Push $6 94 Push $7 95 Push $8 96 Push $9 97 Push $R0 98 99 /* After this point: 100 ------------------------- 101 $0 = ResultVar (returned) 102 $1 = EnvVarName (input) 103 $2 = Action (input) 104 $3 = RegLoc (input) 105 $4 = PathString (input) 106 $5 = Orig EnvVar (read from registry) 107 $6 = Len of $0 (temp) 108 $7 = tempstr1 (temp) 109 $8 = Entry counter (temp) 110 $9 = tempstr2 (temp) 111 $R0 = tempChar (temp) */ 112 113 ; Step 1: Read contents of EnvVarName from RegLoc 114 ; 115 ; Check for empty EnvVarName 116 ${If} $1 == "" 117 SetErrors 118 DetailPrint "ERROR: EnvVarName is blank" 119 Goto EnvVarUpdate_Restore_Vars 120 ${EndIf} 121 122 ; Check for valid Action 123 ${If} $2 != "A" 124 ${AndIf} $2 != "P" 125 ${AndIf} $2 != "R" 126 SetErrors 127 DetailPrint "ERROR: Invalid Action - must be A, P, or R" 128 Goto EnvVarUpdate_Restore_Vars 129 ${EndIf} 130 131 ${If} $3 == HKLM 132 ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 133 ${ElseIf} $3 == HKCU 134 ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 135 ${Else} 136 SetErrors 137 DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' 138 Goto EnvVarUpdate_Restore_Vars 139 ${EndIf} 140 141 ; Check for empty PathString 142 ${If} $4 == "" 143 SetErrors 144 DetailPrint "ERROR: PathString is blank" 145 Goto EnvVarUpdate_Restore_Vars 146 ${EndIf} 147 148 ; Make sure we've got some work to do 149 ${If} $5 == "" 150 ${AndIf} $2 == "R" 151 SetErrors 152 DetailPrint "$1 is empty - Nothing to remove" 153 Goto EnvVarUpdate_Restore_Vars 154 ${EndIf} 155 156 ; Step 2: Scrub EnvVar 157 ; 158 StrCpy $0 $5 ; Copy the contents to $0 159 ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or 160 ; after the last one are not removed here but instead in Step 3) 161 ${If} $0 != "" ; If EnvVar is not empty ... 162 ${Do} 163 ${${UN}StrStr} $7 $0 " ;" 164 ${If} $7 == "" 165 ${ExitDo} 166 ${EndIf} 167 ${${UN}StrRep} $0 $0 " ;" ";" ; Remove '<space>;' 168 ${Loop} 169 ${Do} 170 ${${UN}StrStr} $7 $0 "; " 171 ${If} $7 == "" 172 ${ExitDo} 173 ${EndIf} 174 ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';<space>' 175 ${Loop} 176 ${Do} 177 ${${UN}StrStr} $7 $0 ";;" 178 ${If} $7 == "" 179 ${ExitDo} 180 ${EndIf} 181 ${${UN}StrRep} $0 $0 ";;" ";" 182 ${Loop} 183 184 ; Remove a leading or trailing semicolon from EnvVar 185 StrCpy $7 $0 1 0 186 ${If} $7 == ";" 187 StrCpy $0 $0 "" 1 ; Change ';<EnvVar>' to '<EnvVar>' 188 ${EndIf} 189 StrLen $6 $0 190 IntOp $6 $6 - 1 191 StrCpy $7 $0 1 $6 192 ${If} $7 == ";" 193 StrCpy $0 $0 $6 ; Change ';<EnvVar>' to '<EnvVar>' 194 ${EndIf} 195 ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug 196 ${EndIf} 197 198 /* Step 3. Remove all instances of the target path/string (even if "A" or "P") 199 $6 = bool flag (1 = found and removed PathString) 200 $7 = a string (e.g. path) delimited by semicolon(s) 201 $8 = entry counter starting at 0 202 $9 = copy of $0 203 $R0 = tempChar */ 204 205 ${If} $5 != "" ; If EnvVar is not empty ... 206 StrCpy $9 $0 207 StrCpy $0 "" 208 StrCpy $8 0 209 StrCpy $6 0 210 211 ${Do} 212 ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter 213 214 ${If} $7 == "" ; If we've run out of entries, 215 ${ExitDo} ; were done 216 ${EndIf} ; 217 218 ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) 219 ${Do} 220 StrCpy $R0 $7 1 221 ${If} $R0 != " " 222 ${ExitDo} 223 ${EndIf} 224 StrCpy $7 $7 "" 1 ; Remove leading space 225 ${Loop} 226 ${Do} 227 StrCpy $R0 $7 1 -1 228 ${If} $R0 != " " 229 ${ExitDo} 230 ${EndIf} 231 StrCpy $7 $7 -1 ; Remove trailing space 232 ${Loop} 233 ${If} $7 == $4 ; If string matches, remove it by not appending it 234 StrCpy $6 1 ; Set 'found' flag 235 ${ElseIf} $7 != $4 ; If string does NOT match 236 ${AndIf} $0 == "" ; and the 1st string being added to $0, 237 StrCpy $0 $7 ; copy it to $0 without a prepended semicolon 238 ${ElseIf} $7 != $4 ; If string does NOT match 239 ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, 240 StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon 241 ${EndIf} ; 242 243 IntOp $8 $8 + 1 ; Bump counter 244 ${Loop} ; Check for duplicates until we run out of paths 245 ${EndIf} 246 247 ; Step 4: Perform the requested Action 248 ; 249 ${If} $2 != "R" ; If Append or Prepend 250 ${If} $6 == 1 ; And if we found the target 251 DetailPrint "Target is already present in $1. It will be removed and" 252 ${EndIf} 253 ${If} $0 == "" ; If EnvVar is (now) empty 254 StrCpy $0 $4 ; just copy PathString to EnvVar 255 ${If} $6 == 0 ; If found flag is either 0 256 ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) 257 DetailPrint "$1 was empty and has been updated with the target" 258 ${EndIf} 259 ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), 260 StrCpy $0 $0;$4 ; append PathString 261 ${If} $6 == 1 262 DetailPrint "appended to $1" 263 ${Else} 264 DetailPrint "Target was appended to $1" 265 ${EndIf} 266 ${Else} ; If Prepend (and EnvVar is not empty), 267 StrCpy $0 $4;$0 ; prepend PathString 268 ${If} $6 == 1 269 DetailPrint "prepended to $1" 270 ${Else} 271 DetailPrint "Target was prepended to $1" 272 ${EndIf} 273 ${EndIf} 274 ${Else} ; If Action = Remove 275 ${If} $6 == 1 ; and we found the target 276 DetailPrint "Target was found and removed from $1" 277 ${Else} 278 DetailPrint "Target was NOT found in $1 (nothing to remove)" 279 ${EndIf} 280 ${If} $0 == "" 281 DetailPrint "$1 is now empty" 282 ${EndIf} 283 ${EndIf} 284 285 ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change 286 ; 287 ClearErrors 288 ${If} $3 == HKLM 289 WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section 290 ${ElseIf} $3 == HKCU 291 WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section 292 ${EndIf} 293 294 IfErrors 0 +4 295 MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" 296 DetailPrint "Could not write updated $1 to $3" 297 Goto EnvVarUpdate_Restore_Vars 298 299 ; "Export" our change 300 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 301 302 EnvVarUpdate_Restore_Vars: 303 ; 304 ; Restore the user's variables and return ResultVar 305 Pop $R0 306 Pop $9 307 Pop $8 308 Pop $7 309 Pop $6 310 Pop $5 311 Pop $4 312 Pop $3 313 Pop $2 314 Pop $1 315 Push $0 ; Push my $0 (ResultVar) 316 Exch 317 Pop $0 ; Restore his $0 318 319 FunctionEnd 320 321 !macroend ; EnvVarUpdate UN 322 !insertmacro EnvVarUpdate "" 323 !insertmacro EnvVarUpdate "un." 324 ;----------------------------------- EnvVarUpdate end---------------------------------------- 325 326 !verbose pop 327 !endif
References:
http://stackoverflow.com/questions/11272066/nsis-how-to-set-an-environment-variable-in-system-variable
http://nsis.sourceforge.net/Path_Manipulation
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器