WIX 不卸载旧版本

Wol*_*mit 1 windows-installer 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" />
...

Run Code Online (Sandbox Code Playgroud)

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

应用程序和功能

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

Ste*_*mul 5

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

msiexec.exe /i C:\Path\Your.msi /L*v C:\Your.log
Run Code Online (Sandbox Code Playgroud)

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


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

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

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
Run Code Online (Sandbox Code Playgroud)

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


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


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

  • 升级代码不匹配:新旧版本 MSI 之间的升级代码可能不匹配,因此产品不会被识别为相关产品。这应该会留下安装的两个版本(从未发生过卸载旧版本的情况)。

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

  • 缺少 MajorUpgrade 元素:整个 Major Upgrade 元素可能会丢失并且不存在 Upgrade 元素。后者用于手动配置重大升级,前者用于“自动神奇”实施典型重大升级场景。有点“最佳实践”。

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

  • 产品代码:作为旁注,您可能会收到一条警告,表明产品已安装,这意味着产品代码尚未更改(主要升级应该如此)。

  • 悬挂版本:也有可能您的 WiX 标记很好,并且您有一个从未正确配置的悬挂旧版本,如果是这样,请手动卸载它并重试或尝试使用干净的虚拟机。如果您自动生成产品 GUID,并且未正确设置主要升级,则最终可能会同时安装产品的多个版本。通常,您可以从“添加/删除程序”小程序卸载所有这些版本。您还可以找到涉及的产品 G​​UID,并通过您选择的机制进行卸载: 卸载 MSI 文件的不同方法

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

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

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

更多细节:还有一些需要记住的事情:

  • 主要升级本质上是卸载旧版本并安装新版本,并具有许多操作发生顺序的计划选项(先安装新版本,然后卸载旧版本,反之亦然)。

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

  • 对于 WiX 来说不太可能,但 InstallExecuteSequence 中可能会缺少标准操作“RemoveExistingProducts”。

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

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

msiexec.exe /i C:\Path\Your.msi /L*v C:\Your.log
Run Code Online (Sandbox Code Playgroud)

请参阅生成的升级表

虎鲸

测试案例:使用透明铝作为测试项目,您可以尝试以下程序来使升级工作:

  1. 将产品代码设置为*以便为每个构建自动生成新的 ProductCode (" <Product Id="*" ...")。
  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 以删除相关产品

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


链接

  • 这是正确的,[MSI SDK 文档中已说明](https://learn.microsoft.com/en-us/windows/win32/msi/productversion)(您读过它后仍然会问吗?)。另外:答案也是为其他人编写的 - 用于一般目的的重复使用。重新表述以前写过的内容是一种练习和实验,看看是否可以做得更好。 (2认同)

归档时间:

查看次数:

4281 次

最近记录:

2 年,6 月 前