简体   繁体   English

如果检测到相同版本,则升级引导程序包

[英]Upgrade a bootstrapper bundle if the same version is detected

I have a WiX bootstrapper bundle:我有一个 WiX 引导程序包:

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

When I generate a new build and try to install it over a previous installation, the bootstrapper should upgrade itself (since its the same version), however it will leave the old version of itself lying around in Programs and Features.当我生成一个新版本并尝试在以前的安装上安装它时,引导程序应该自行升级(因为它的版本相同),但是它会将旧版本的自身留在程序和功能中。 What can I do to uninstall the previous version completely if installing over the same version, and how can I remove the old build from Programs and Features?如果在同一版本上安装,我该怎么做才能完全卸载以前的版本,以及如何从程序和功能中删除旧版本? I have looked online but there aren't any clear answers on this topic.我在网上看过,但没有关于这个话题的明确答案。

Edit : This question hints to use a custom BA to override the default no-op behavior by changing the request state in OnPlanRelatedBundle.编辑这个问题提示使用自定义 BA 通过更改 OnPlanRelatedBundle 中的请求状态来覆盖默认的无操作行为。 I'm not sure what people mean by this, or how I can hook into OnPlanRelatedBundle...can anyone clarify?我不确定人们的意思是什么,或者我如何才能连接到 OnPlanRelatedBundle ......有人可以澄清一下吗? Is custom BA = custom build action?自定义 BA = 自定义构建操作吗?

Sorry to revive an old post, but as there is still no native support for this as of WiX 3.10, I thought I would post my work-around.很抱歉恢复旧帖子,但由于 WiX 3.10 仍然没有对此的本地支持,我想我会发布我的解决方法。

The caveat to this method is that double-clicking a package that you've just installed will not bring up the usual 'modify, uninstall' dialog.这种方法需要注意的是,双击刚刚安装的软件包不会弹出通常的“修改、卸载”对话框。 What I've done to handle this is put in a <bal:Condition> which instructs the user to use 'Add Remove Programs' if they wish to invoke the uninstall or modify functionality.我为处理此问题所做的工作是放在<bal:Condition>中,如果用户希望调用卸载或修改功能,它会指示用户使用“添加删除程序”。

The reason I need this at all, instead of just incrementing Version to perform an upgrade, is that we have online and offline bundles.我之所以需要这个,而不是仅仅增加版本来执行升级,是因为我们有在线和离线捆绑包。 I want to prevent them from being installed simultaneously.我想防止它们同时安装。

Another thing that this approach requires is that your bundle version ID matches your MSI version ID.此方法需要的另一件事是您的捆绑版本 ID 与您的 MSI 版本 ID 匹配。 Enough disclaimers, here's the approach:足够的免责声明,这是方法:

Create a Product search, but importantly, use the UpgradeCode for your MSI package, not for the bundles!创建产品搜索,但重要的是,将UpgradeCode用于您的 MSI 包,而不是捆绑包! ProductSearch will never find your Bundle's GUID because the Bundle is an .exe and not an MSI. ProductSearch 永远不会找到您的 Bundle 的 GUID,因为 Bundle 是 .exe 而不是 MSI。

<util:ProductSearch
        Variable="BundleAlreadyInstalled"
        UpgradeCode="MSI-GUID-NOT-BUNDLE-GUID"
        Id="BundleAlreadyInstalledSearch"
        Result="version"
                />

Next, inside your <bundle> elements, add the following:接下来,在<bundle>元素中,添加以下内容:

<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>

The core of the hack here is that we are using the MSI's Version (which as I said must match the Bundle's Version for this reason) as the key indicator to whether this bundle is present on the target system.这里破解的核心是我们使用 MSI 的版本(正如我所说的,它必须与捆绑包的版本匹配)作为该捆绑包是否存在于目标系统上的关键指标。

If you don't include NOT WixBundleAction = 5 you will not be able to uninstall the application, which is kind of important.如果您不包括NOT WixBundleAction = 5 ,您将无法卸载应用程序,这很重要。

As for the second part, we want to specifically detect whether this version is already installed.至于第二部分,我们要专门检测是否已经安装了这个版本。 Upgrades and downgrades will fail this test, which is what we want because the normal logic would kick in and perform your upgrade/downgrade.升级和降级将无法通过此测试,这是我们想要的,因为正常逻辑会启动并执行您的升级/降级。

Without this bit of logic, it was possible for my users to install both the online and offline versions of the bundle simultaneously.如果没有这一点逻辑,我的用户可以同时安装捆绑包的在线和离线版本。 The primary reason for that is that the Bundle@Id is generated by WiX.主要原因是Bundle@Id是由 WiX 生成的。 Another more subtle problem that this fixes is that simply rebuilding a Bundle without modifying the Version will also allow you to install it side-by-side!此修复的另一个更微妙的问题是,只需在不修改版本的情况下重新构建 Bundle 也将允许您并排安装它! You will get duplicate entries in 'Add Remove Programs' for all of these.您将在“添加删除程序”中获得所有这些重复条目。

These problems are completely prevented by these few lines of code.这几行代码完全避免了这些问题。 As I mentioned, the trade-off is that installing, and subsequently running the exact bundle again will not trigger the uninstallation dialog, but this is a whole lot easier to live with than duplicate ARP entries.正如我所提到的,权衡是安装并随后再次运行确切的捆绑包不会触发卸载对话框,但这比重复的 ARP 条目要容易得多。 Especially since you can just provide instructions in the error message.特别是因为您可以在错误消息中提供说明。

尝试在您的引导程序中指定一个 RelatedBundle 元素。

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

v4.0 changed the default behavior to make it upgrade when it is the same version. v4.0 更改了默认行为,使其在相同版本时进行升级。

In v3.x, you need a custom BootstrapperApplication.在 v3.x 中,您需要一个自定义的 BootstrapperApplication。

I found a way around my problem without modifying the WiX burn source code.我在不修改 WiX 刻录源代码的情况下找到了解决问题的方法

I disabled my bootstrapper bundle from showing up in Programs and Features:我禁止我的引导程序包出现在程序和功能中:

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

I didn't really need it to show up.我真的不需要它出现。 I just needed the package it bundles and installs to show up, really.我只需要它捆绑和安装的软件包才能显示出来,真的。 Then, I just made it show the MSI package it installed, instead:然后,我只是让它显示它安装的 MSI 包,而不是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM