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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:20:14