WIX 3.11大版本升级:如何让旧BA卸载自身旧包?
解决WIX 3.11 Bundle大版本升级时旧BA未执行卸载的问题
问题根源
默认MSI层面的<MajorUpgrade>会直接触发旧MSI的卸载,这个过程完全由Windows Installer管控,不会唤起旧Bundle的托管BA,导致BA卸载时设置的自定义变量无法传递给旧MSI的卸载流程。要解决这个问题,需要把升级的控制权从MSI转移到Bundle,让旧BA主动执行卸载逻辑。
具体解决方案
1. 禁用MSI自身的自动卸载逻辑
注释或替换原MSI中的<MajorUpgrade>元素,避免MSI自行触发旧版本卸载,改为仅检测旧版本存在:
<!-- 移除原MajorUpgrade,替换为仅版本检测的Upgrade元素 --> <Upgrade Id="YOUR-MSI-UPGRADE-CODE-GUID"> <UpgradeVersion Minimum="1.0.0.0" Maximum="$(var.ProductVersion)" IncludeMinimum="yes" IncludeMaximum="no" Property="OLD_MSI_FOUND" /> </Upgrade> <!-- 在InstallExecuteSequence中添加检测,若存在旧版本则终止MSI安装,引导用户使用Bundle升级 --> <CustomAction Id="BlockOldVersion" Error="请使用最新的Bundle安装包进行升级" /> <InstallExecuteSequence> <Custom Action="BlockOldVersion" After="FindRelatedProducts">OLD_MSI_FOUND</Custom> </InstallExecuteSequence>
2. 配置Bundle的升级流程,唤起旧BA执行卸载
在Bundle中配置升级检测,找到旧Bundle后调用其卸载命令,让旧BA接管卸载:
<Bundle UpgradeCode="YOUR-BUNDLE-UPGRADE-CODE-GUID" Version="$(var.BundleVersion)"> <!-- 检测旧版本Bundle --> <Upgrade Id="YOUR-BUNDLE-UPGRADE-CODE-GUID"> <UpgradeVersion Minimum="1.0.0.0" Maximum="$(var.BundleVersion)" IncludeMinimum="yes" IncludeMaximum="no" Property="OLD_BUNDLE_FOUND" /> </Upgrade> <Chain> <!-- 先执行旧Bundle的卸载,唤起旧BA --> <ExePackage SourceFile="[WixBundleOriginalSourceFolder]OldBundle.exe" DetectCondition="OLD_BUNDLE_FOUND" InstallCommand="/uninstall /passive" InstallCondition="OLD_BUNDLE_FOUND" Permanent="no" Vital="yes" /> <!-- 再安装新版本MSI --> <MsiPackage SourceFile="path/to/NewProduct.msi" /> </Chain> </Bundle>
注意:
[WixBundleOriginalSourceFolder]是WIX内置变量,指向当前Bundle的运行目录,若旧Bundle的exe路径有变化,可通过注册表读取旧Bundle的安装路径来定位。
3. 让旧BA支持卸载命令行参数
在旧Bundle的托管BA代码中,解析命令行参数,当接收到卸载指令时执行卸载流程并设置所需变量:
protected override void Run() { string commandLine = Engine.CommandLine; if (commandLine.IndexOf("/uninstall", StringComparison.OrdinalIgnoreCase) >= 0) { // 设置卸载所需的自定义属性/变量 Engine.SetVariable("UNINSTALL_CUSTOM_PROPERTY", "required_value"); // 规划并执行卸载 Engine.Plan(LaunchAction.Uninstall); int result = Engine.Apply(IntPtr.Zero); Exit(result); } // 原有安装/修复逻辑 // ... }
4. 验证流程
调整完成后,执行大版本升级时应该生成以下日志:
- 旧BA的卸载日志(确认自定义变量已设置并传递给旧MSI)
- 新BA的运行日志
- 新MSI的安装日志
内容的提问来源于stack exchange,提问作者Christoph Thien
相关产品推荐
相关产品推荐

