WIX自定义引导程序主程序卸载时如何询问并联动卸载插件
实现主程序卸载时联动卸载插件的WIX方案
我之前做过类似的场景,刚好可以分享下具体的实现步骤,核心思路是注册表检测插件存在性 + 自定义卸载对话框 + 执行插件卸载命令:
1. 检测插件的卸载注册表项
插件作为独立安装程序,肯定会在HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{插件产品GUID}(32位系统对应HKLM\Software\Wow6432Node\...)下存在卸载相关键值,比如UninstallString。我们需要在主程序的WIX项目里添加注册表搜索,获取这个卸载命令:
<Property Id="PLUGIN_UNINSTALL_STRING"> <RegistrySearch Id="FindPluginUninstallString" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\{你的插件产品GUID}" Name="UninstallString" Type="raw" /> </Property> <!-- 兼容64位系统的32位程序注册表路径 --> <Property Id="PLUGIN_UNINSTALL_STRING_WOW64"> <RegistrySearch Id="FindPluginUninstallStringWow64" Root="HKLM" Key="Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{你的插件产品GUID}" Name="UninstallString" Type="raw" Win64="yes" /> </Property> <!-- 合并两个搜索结果,确保全系统位数兼容 --> <CustomAction Id="SetPluginUninstallString" Property="PLUGIN_UNINSTALL_STRING" Value="[PLUGIN_UNINSTALL_STRING_WOW64]" Execute="immediate" HideTarget="no" Return="check" />
然后把这个自定义动作加入安装序列,放在启动条件之后执行:
<InstallUISequence> <Custom Action="SetPluginUninstallString" After="LaunchConditions">NOT Installed</Custom> </InstallUISequence> <InstallExecuteSequence> <Custom Action="SetPluginUninstallString" After="LaunchConditions">NOT Installed</Custom> </InstallExecuteSequence>
2. 添加自定义卸载询问对话框
接下来要在卸载流程中加一个弹窗,只有检测到插件存在时才显示。先定义对话框:
<Dialog Id="UninstallPluginPrompt" Width="370" Height="270" Title="[ProductName] 卸载"> <Control Id="PromptText" Type="Text" X="45" Y="70" Width="280" Height="60" NoPrefix="yes"> <Text>检测到已安装的[插件名称]插件,是否同时卸载该插件?</Text> </Control> <Control Id="YesBtn" Type="PushButton" X="120" Y="170" Width="56" Height="17" Default="yes" Cancel="no"> <Text>&是</Text> <Publish Event="DoAction" Value="UninstallPlugin">1</Publish> <Publish Event="EndDialog" Value="Return">1</Publish> </Control> <Control Id="NoBtn" Type="PushButton" X="200" Y="170" Width="56" Height="17" Default="no" Cancel="yes"> <Text>&否</Text> <Publish Event="EndDialog" Value="Return">1</Publish> </Control> <Control Id="CancelBtn" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes"> <Text>&取消</Text> <Publish Event="EndDialog" Value="Exit">1</Publish> </Control> </Dialog>
再把这个对话框加入卸载UI序列,仅在全量卸载且插件存在时触发:
<InstallUISequence> <Show Dialog="UninstallPluginPrompt" After="MigrateFeatures">REMOVE="ALL" AND PLUGIN_UNINSTALL_STRING</Show> </InstallUISequence>
3. 实现插件卸载的自定义动作
用WIX的WixQuietExec来执行插件的卸载命令(需要先引用WixUtilExtension扩展):
<!-- 执行卸载命令的自定义动作 --> <CustomAction Id="UninstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="check" Impersonate="no" /> <!-- 设置卸载命令,替换参数为静默卸载模式 --> <CustomAction Id="SetUninstallPluginCmd" Property="UninstallPlugin" Value=""[PLUGIN_UNINSTALL_STRING]" /X {你的插件产品GUID} /qn" Execute="immediate" Return="check" />
最后把动作加入执行序列,确保在主程序文件删除前完成插件卸载:
<InstallExecuteSequence> <Custom Action="SetUninstallPluginCmd" Before="UninstallPlugin">REMOVE="ALL" AND PLUGIN_UNINSTALL_STRING</Custom> <Custom Action="UninstallPlugin" Before="RemoveFiles">REMOVE="ALL" AND PLUGIN_UNINSTALL_STRING</Custom> </InstallExecuteSequence>
4. 关键注意事项
- 产品GUID要准确:替换成你插件的真实产品GUID,可在插件WIX项目或注册表中查询。
- 静默卸载参数:
/qn是完全静默模式,避免插件卸载时弹出自身对话框干扰流程;如果需要简化交互,可换成/qb。 - 权限设置:自定义动作要设
Impersonate="no",确保以系统权限执行卸载操作。 - 多场景测试:要验证三种情况:插件未安装时主程序正常卸载;插件已安装时弹窗询问,选择"是"则两者都卸载;选择"否"则仅卸载主程序。
内容的提问来源于stack exchange,提问作者Maddie
相关产品推荐
相关产品推荐

