关于 .net:如果检测到相同版本,则升级引导程序包

Upgrade a bootstrapper bundle if the same version is detected

我有一个 WiX 引导程序包:

1
<Bundle Name="blah" Version="1.0.0" Manufacturer="blah" UpgradeCode="some-guid-string">

当我生成一个新版本并尝试在以前的安装上安装它时,引导程序应该自行升级(因为它的版本相同),但是它会在程序和功能中留下旧版本。如果在同一版本上安装,我该怎么做才能完全卸载以前的版本,以及如何从程序和功能中删除旧版本?我在网上看过,但没有关于这个话题的明确答案。

编辑:此问题提示使用自定义 BA 通过更改 OnPlanRelatedBundle 中的请求状态来覆盖默认的无操作行为。我不确定人们的意思是什么,或者我如何才能连接到 OnPlanRelatedBundle ......有人可以澄清一下吗?自定义 BA = 自定义构建操作吗?


很抱歉恢复旧帖子,但由于 WiX 3.10 仍然没有对此的本地支持,我想我会发布我的解决方法。

此方法的注意事项是双击您刚刚安装的软件包不会弹出通常的"修改、卸载"对话框。我为处理此问题所做的工作放在 <bal:Condition> 中,如果用户希望调用卸载或修改功能,它会指示用户使用"添加删除程序"。

我之所以需要这个,而不是仅仅增加版本来执行升级,是因为我们有在线和离线捆绑包。我想防止它们同时安装。

此方法要求的另一件事是您的捆绑包版本 ID 与您的 MSI 版本 ID 匹配。足够的免责声明,这是方法:

创建产品搜索,但重要的是,将 UpgradeCode 用于您的 MSI 包,而不是捆绑包! ProductSearch 永远不会找到您的 Bundle\\ 的 GUID,因为 Bundle 是 .exe 而不是 MSI。

1
2
3
4
5
6
<util:ProductSearch
        Variable="BundleAlreadyInstalled"
        UpgradeCode="MSI-GUID-NOT-BUNDLE-GUID"
        Id="BundleAlreadyInstalledSearch"
        Result="version"
                />

接下来,在您的 <bundle> 元素中,添加以下内容:

1
2
3
4
<Variable Name="CurrentVersionNumber" Type="string" Value="$(var.Version)" />
<bal:Condition Message="Tell your user to use Add Remove Programs here.">
    NOT WixBundleAction = 5 OR NOT BundleAlreadyInstalled = CurrentVersionNumber
</bal:Condition>

这里破解的核心是我们使用 MSI 的版本(因为这个原因,它必须与捆绑包的版本匹配)作为这个捆绑包是否存在于目标上的关键指标系统。

如果您不包含 NOT WixBundleAction = 5,您将无法卸载应用程序,这很重要。

至于第二部分,我们要专门检测是否已经安装了这个版本。升级和降级将无法通过此测试,这是我们想要的,因为正常逻辑会启动并执行您的升级/降级。

如果没有这些逻辑,我的用户可以同时安装捆绑包的在线和离线版本。主要原因是 Bundle@Id 是由 WiX 生成的。此修复的另一个更微妙的问题是,只需在不修改版本的情况下重新构建 Bundle 也将允许您并排安装它!您将在"添加删除程序"中获得所有这些重复条目。

这几行代码完全避免了这些问题。正如我所提到的,权衡是安装并随后再次运行确切的捆绑包不会触发卸载对话框,但这比重复的 ARP 条目要容易得多。特别是因为您可以在错误消息中提供说明。


尝试在 Bootstrapper 中指定一个 RelatedBundle 元素。

1
<RelatedBundle Id="THE-BUNDLE-UPGRADE-GUID" Action="Upgrade"/>

我在不修改 WiX 刻录源代码的情况下找到了解决问题的方法。

我禁止我的引导程序包显示在程序和功能中:

1
<Bundle DisableRemove="yes" DisableModify="yes" ... />

我真的不需要它出现。我只需要它捆绑和安装的软件包才能显示出来,真的。然后,我只是让它显示它安装的 MSI 包,而不是:

1
<MsiPackage Visible="yes" ... />