You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSIS多实例产品卸载时注册表键未删除的问题

NSIS多实例卸载注册表键无法删除问题解决

问题核心

开发支持多实例部署的NSIS安装包时,通过!define appname 'vpmapclient$Environment'动态生成test/live实例对应的注册表键(如vpmapclient-test),安装后能正常显示在「程序和功能」中,但卸载时DeleteRegKey无法移除对应注册表键,导致条目残留;若用固定常量定义appname则卸载正常。

根因分析

!define是NSIS的编译时指令,在脚本编译阶段就会完成变量替换。如果$Environment是安装过程中才确定的运行时变量(比如通过命令行参数传入),那么主安装脚本编译时,$Environment还没有实际值,!define appname 'vpmapclient$Environment'会被解析成字符串vpmapclient$Environment,而非实际的vpmapclient-test或vpmapclient-live。

生成的卸载器中,${appname}会保留这个错误的固定字符串,卸载时尝试删除vpmapclient$Environment这个不存在的注册表键,自然无法清理「程序和功能」条目。而用常量定义时,appname是编译时确定的固定值,卸载器能正确匹配目标键,所以删除正常。

解决方案

改用运行时变量传递实例名称给卸载器,确保卸载时能获取到正确的注册表键名。

修改后的安装代码

; 替换编译时!define为运行时变量赋值
StrCpy $AppName "vpmapclient$Environment"

; 写入实例专属注册表项(使用运行时变量$AppName)
WriteRegStr HKLM "SOFTWARE\Company\$AppName" "Install_Dir" "$INSTDIR"
WriteRegStr HKLM "SOFTWARE\Company\$AppName" "DisplayVersion" "${_VERSION}"

; 写入「程序和功能」卸载注册表项(使用$AppName)
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "DisplayName" "Company Product $Environment"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "Publisher" "Company"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "VersionMajor" ${VERSIONMAJOR}
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "VersionMinor" ${VERSIONMINOR}
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "Version" 0x02000000
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "DisplayVersion" "${_VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "UninstallString" '"$INSTDIR\product_uninstall.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "DisplayIcon" "$INSTDIR\Product.ico"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "EstimatedSize" "$EstimatedSize"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "NoRepair" 1

; 生成卸载器时,将实际的AppName传递为卸载器的编译时变量
WriteUninstaller /D=APPNAME="$AppName" "$InstDir\product_uninstall.exe"

修改后的卸载代码

; 接收安装时传递的APPNAME变量
!define APPNAME "${APPNAME}"

DetailPrint "===Removing Registry Keys for ${APPNAME}==="
; 删除对应实例的注册表键
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
DeleteRegKey HKLM "SOFTWARE\Company\${APPNAME}"

备选方案(从注册表读取实例名)

如果无法通过WriteUninstaller传递变量,可在安装时将实例名写入卸载注册表项,卸载时读取后再删除:

安装时新增写入:

WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName" "AppName" "$AppName"

卸载时读取并删除:

; 读取当前卸载项对应的实例名
ReadRegStr $AppName HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY}" "AppName"

DetailPrint "===Removing Registry Keys for $AppName==="
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$AppName"
DeleteRegKey HKLM "SOFTWARE\Company\$AppName"

内容的提问来源于stack exchange,提问作者tcweb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:52:00