Windows 安装程序在产品升级期间删除版本控制文件,而不是将其降级

发布于 2024-10-03 21:49:16 字数 785 浏览 0 评论 0原文

我们使用 wix 来创建我们的设置。对于升级,我们使用主要升级,如 Rob Mensching 的回答< /a>. (在较新的 wix 版本中,您可以使用 MajorUpgrade 元素。)这通常效果很好。删除旧产品,然后安装新产品。

但是,显然上述并不完全等同于手动卸载旧产品然后手动安装新产品。

例如,考虑以下场景:

  • 我们产品的版本 1.0 发布,包含第三方 dll 的版本 5.0
  • 我们产品的版本 1.1 发布,包含同一第三方 dll 的版本 5.1
  • 我们产品的版本 1.2 发布,降级到版本 5.0再次使用第三方dll,因为我们发现新版本引入的问题多于它解决的问题。

显然,根据上面链接的 wix 升级逻辑,从版本 1.1 升级到 1.2 时,3rdparty dll 将消失。需要进行修复才能恢复它。

是否有另一种升级方法适用于这种情况?我想我正在寻找的是升级逻辑,它允许组件降级,其行为就像手动卸载旧产品然后手动安装新产品一样。

We use wix to create our setups. For upgrading, we use major upgrades as demonstrated in this answer by Rob Mensching. (In newer wix versions you can use the MajorUpgrade element.) This normally works well. The old product is removed, then the new product is installed.

However, apparently the above is not completely equivalent to manually uninstalling the old product and then manually installing the new product.

Consider for example the following scenario:

  • version 1.0 of our product is released, containing version 5.0 of a thirdparty dll
  • version 1.1 of our product is released, containing version 5.1 of the same thirdparty dll
  • version 1.2 of our product is released, downgrading to version 5.0 of the thirdparty dll again because we discovered that the new version introduced more problems than it solved.

Apparently with the wix upgrade logic linked above, the 3rdparty dll will disappear when upgrading from release 1.1 to 1.2. A repair is necessary to restore it.

Is there another way to upgrade, which would work for this scenario? I guess what I am looking for is upgrade logic which allows the downgrading of components, by behaving exactly as if one manually uninstalls the old product and then manually installs the new product.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

记忆消瘦 2024-10-10 21:49:16

我们还遇到了这个问题,即在重大升级时未重新安装较低版本的 DLL。我觉得很奇怪的是,安装程序会根据现有文件的版本控制来决定安装哪些文件,然后完全卸载所有内容,但仍然只安装之前确定要安装的文件卸载旧产品。这看起来可能是 Windows Installer 中的错误...

为了解决此问题,我们将 RemoveExistingProducts 操作移至 CostFinalize 操作上方。

我了解MSDN 上的文档建议将RemoveExistingProducts after InstallValidate,我不确定将其放在 InstallValidate 操作之前是否会对次要升级产生任何负面影响,但我们有决定只对我们的产品进行重大升级,因此该解决方案似乎适合我们。

We also encountered this problem where lower-versioned DLLs were not getting reinstalled on a major upgrade. I thought it was strange that the installer would decide which files to install based on the versioning of existing files, then completely uninstall everything, but still only install what what files had been determined to install before uninstalling the old product. This seems like it might be a bug in Windows Installer...

To fix this problem we moved the RemoveExistingProducts action above the CostFinalize action.

I know the documentation on MSDN recommends placing the RemoveExistingProducts afterInstallValidate, and I'm not sure if putting it before the InstallValidate action has any negative side effects for minor upgrades, but we have decided to only perform major upgrades for our products so this solution appears to work for us.

四叶草在未来唯美盛开 2024-10-10 21:49:16

此类行为通常与 RemoveExistingProducts 的排序有关。如果发生得足够晚,Windows Installer 将发现计算机上有较新版本的 .dll,因此不需要安装 1.2 版。然而,当RemoveExistingProducts导致删除.dll时,没有任何东西可以将其恢复。

可以尝试的事情包括更改RemoveExistingProducts的顺序,以及谎报1.2包中的.dll版本(报告比错误版本号更高的版本号)。后者的缺点是对修复或修补影响不大,因为 .dll 看起来总是过时的。

Behaviors like this generally have to do with the sequencing of RemoveExistingProducts. If it occurs late enough, Windows Installer will have figured out that there's a newer version of the .dll on the machine, so version 1.2 doesn't need to install it. However when the RemoveExistingProducts results in removing the .dll, nothing puts it back.

Things to try including changing the sequencing of RemoveExistingProducts, and lying about the version of the .dll in your 1.2 package (report a version number higher than the bad one). The downside of the latter is poor impacts on repairs or patching, as the .dll always looks out of date.

可可 2024-10-10 21:49:16

尝试提前安排RemoveExistingProducts,对吧在 InstallValidate 之后,更改 的值将 REINSTALLMODE 属性设置为 amus。这样,在复制新产品中的任何文件之前,旧产品将被完全删除,并且 a 模式将强制重新安装这些文件。

Try to schedule RemoveExistingProducts earlier, right after InstallValidate, and change the value of REINSTALLMODE property to amus. This way the old product will be completely removed before any files from the new product are copied, and a mode will force re-install of the files.

爱,才寂寞 2024-10-10 21:49:16

多年后,这条线索帮助我走向了正确的方向。在成本计算之前移动 RemoveExisitingProducts 的完整性示例:

<Upgrade Id="UPGRADE-GUID-HERE">
    <UpgradeVersion OnlyDetect="no" Property="UPGRADABLEFOUND"
        Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
    <UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
        Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>

<InstallExecuteSequence>
    <Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
    <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>

<CustomAction Id="NoDowngrade" Error="A newer version of $(var.ProductName) is already installed." />

Years later, this thread helped me in the right direction. An example for completeness with RemoveExisitingProducts moved before costing:

<Upgrade Id="UPGRADE-GUID-HERE">
    <UpgradeVersion OnlyDetect="no" Property="UPGRADABLEFOUND"
        Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
    <UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
        Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>

<InstallExecuteSequence>
    <Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
    <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>

<CustomAction Id="NoDowngrade" Error="A newer version of $(var.ProductName) is already installed." />
明月夜 2024-10-10 21:49:16

这是次优的,但我通过重命名第三方 dll 并更改 .wxs 文件中与其关联的组件节点上的 GUID 解决了同样的问题。

It's sub-optimal, but I fixed the same problem by renaming the third party dll and changing the GUID on the component node associated with it in the .wxs file.

何时共饮酒 2024-10-10 21:49:16

这是我基于@Spacemani给出的答案的最终解决方案。

它生成与此类似的 MSI 表条目(升级、LaunchCondition 等),

<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />

但使您可以完全控制 InstallExecuteSequence。

<!-- Product upgrade -->
<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion OnlyDetect="no" Property="WIX_UPGRADE_DETECTED"
                  Maximum="$(var.ProductVersion)" IncludeMaximum="no" IncludeMinimum="no"
                  MigrateFeatures="yes" />
  <UpgradeVersion OnlyDetect="yes" Property="WIX_DOWNGRADE_DETECTED"
                  Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
  <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<Condition Message="!(loc.DowngradeErrorMessage)">NOT WIX_DOWNGRADE_DETECTED</Condition>

请注意,您需要像这样抑制 .wixproj 文件中的 ICE27 错误。

<PropertyGroup>
  <SuppressIces>ICE27</SuppressIces>
</PropertyGroup>

Here's my final solution based on the answer given by @Spacemani.

It produces MSI table entries (Upgrade, LaunchCondition etc.) similar to this

<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />

but gives you full control of the InstallExecuteSequence.

<!-- Product upgrade -->
<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion OnlyDetect="no" Property="WIX_UPGRADE_DETECTED"
                  Maximum="$(var.ProductVersion)" IncludeMaximum="no" IncludeMinimum="no"
                  MigrateFeatures="yes" />
  <UpgradeVersion OnlyDetect="yes" Property="WIX_DOWNGRADE_DETECTED"
                  Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
  <RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<Condition Message="!(loc.DowngradeErrorMessage)">NOT WIX_DOWNGRADE_DETECTED</Condition>

Note that you need to suppress ICE27 errors in your .wixproj file like this.

<PropertyGroup>
  <SuppressIces>ICE27</SuppressIces>
</PropertyGroup>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文