首页 > 解决方案 > WIX 不会卸载旧版本

问题描述

经过一番谷歌搜索后,我想出了一个配置,该配置应该允许我只安装我的软件包的较新版本(它可以),同时替换旧的,已经安装的版本(它没有)

我的 wxs 文件如下:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
             Name="Gdml File Viewer" Language="1033"
             UpgradeCode="5fb07c15-32a5-4b8a-9794-e4425bfc2eea"
             ...>
        <Package InstallerVersion="200"
                 Compressed="yes"
                 InstallScope="perMachine" Platform="x64" />
        <MajorUpgrade Schedule="afterInstallValidate"
                      DowngradeErrorMessage="A later version of [ProductName] is already installed"
                 AllowSameVersionUpgrades="no"
                 AllowDowngrades="no" />
...

正如预期的那样,它确实允许我安装较新的版本,但未卸载旧版本。它仍然显示在“应用程序和功能”列表中:

应用程序和功能

(另一个实例的版本为 2019.14.181.35181)

标签: wixwindows-installer

解决方案


日志记录:要正确调试失败的主要升级,您需要创建一个正确的日志文件(创建日志文件的各种方法 - 也通过策略)。

msiexec.exe /i C:\Path\Your.msi /L*v C:\Your.log

可以打开自动记录:检查 TEMP 文件夹中是否有任何自动生成的日志文件。如果没有,请在虚拟机上再次运行以重现启用日志记录的升级问题。


主要升级失败:当您在添加/删除程序中看到两个条目时,您的主要升级失败(通常)。您需要修复升级表的配置。请参阅下面列出的可能原因。

最小 WiX 标记:默认升级表的最小 WiX 标记 - 具有正常参数(工作正常,请参见下面的屏幕截图) - 只是:

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

高级:甚至可以将上述用于简单主要升级配置的“便利元素”与旧式元素结合起来,以完全控制升级表的内容。样品在这里


关于主要升级:MajorUpgrade 和 Upgrade 元素。如何使用它们:


可能的原因:主要升级失败的许多可能原因的简短摘要。

  • 升级代码不匹配:新旧版本的 MSI 之间的升级代码可能不匹配,因此无法将产品识别为相关产品。这应该会在之后安装两个版本(从未卸载旧版本)。

  • 缺少升级代码:只需添加升级代码可能会从产品元素中丢失。这通常是一个错误,除非你想做一些特别奇怪的事情。

  • 缺少 MajorUpgrade 元素:可能缺少整个 Major Upgrade 元素并且不存在 Upgrade 元素。后者用于重大升级的手动配置,前者用于典型重大升级场景的“自动魔术”实施。某种“最佳实践”。

  • ProductVersion:产品版本中的前 3 位数字中的一个或多个可能没有增加(忽略第四个字段)。

  • 产品代码:作为旁注,您可能会收到产品已安装的警告,这意味着产品代码没有更改(它应该用于重大升级)。

  • 悬空版本:您的 WiX 标记也可能很好,并且您有一个从未正确配置的悬空旧版本,如果是这样,请手动卸载它并重试或尝试干净的虚拟。如果您自动生成产品 GUID,如果主要升级设置不正确,您最终可能会同时安装多个版本的产品。

  • 安装上下文:MSI 文件可以按用户或按机器安装。如果您有按用户安装,然后运行按机器安装,它将不会检测到以前的版本。您的包中有对 ALLUSERS 的硬编码引用吗?

  • SecureCustomProperties:很快 - 我记得 - 在安全环境(用户在没有管理员权限的情况下运行的企业环境)中,您需要将升级表中的 ACTION 属性添加到安全属性列表(允许将属性传递到延迟模式)。

  • 包代码:我见过的一种非常特殊的情况是,新包与旧包(或现有安装的包)具有相同的包代码。这是一个极端的设计错误,绝不能发生。始终自动生成包代码,这是做事的正确方式。Windows Installer 将根据定义将这两个包视为相同的(与实际情况相反 - 您不会相信可能产生的 X 文件)。

更多细节:需要记住的一些进一步的事情:

  • 主要升级本质上是卸载旧版本并安装新版本,其中包含多个调度选项,用于操作发生的顺序(先安装新版本,然后卸载旧版本,反之亦然)。

  • 如上所述,您还可能在未正确配置的盒子上安装了零散的旧版本,或者发生了一些 X-Files 废话,导致升级失败。发生。

  • WiX 不太可能,但标准操作 RemoveExistingProducts 可能会从 InstallExecuteSequence 中丢失。

WiX 学习曲线:建议使用一些示例来帮助加快学习过程。唯一真正有用的是什么?以下是一些 WiX 快速入门建议。那里有示例链接。

最小的 WiX 样品:有这个旧样品:透明铝。本质上是如何使用Votive创建基于 WiX 的安装程序的演练。它包括一个主要的升级元素。我相信这个简单的配置增加了您寻求的降级保护:

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

查看升级表,结果如下:

逆戟鲸

测试用例:使用透明铝作为测试项目,您可以尝试此过程以使升级工作:

  1. 将产品代码设置为*以便为每个构建 (" <Product Id="*" ...") 自动生成一个新的 ProductCode。
  2. 编译您的 MSI 的第一个版本。在解决方案视图中右键单击 WiX 项目,Visual Studio然后选择Open Folder in File Explorer. 进入binDebugRelease
  3. 通过在文件名末尾添加 _1 来重命名已编译的 MSI。例如:MySetup_1.msi
  4. 现在增加 WiX 源中产品版本字段的前 3 位数字之一:<Product Id="*" ... Version="2.0.0"
  5. 编译一个新的 MSI 并重命名它:MySetup_2.msi
  6. 从版本 1 开始安装 MSI 文件,然后安装第二个。验证主要升级是否成功。

高级:这是一个使用便利元素"MajorUpgrade"和旧"Upgrade"元素的组合配置主要升级的高级方法的演示(允许您对生成的升级表进行更细粒度的控制):

向 MSI UpgradeTable 添加条目以删除相关产品

以下是仅使用较旧的升级元素导致更多工作的示例,但对升级表的完全控制:主要升级 - “旧的手动方式”


链接


推荐阅读