wix - 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)
解决方案
日志记录:要正确调试失败的主要升级,您需要创建一个正确的日志文件(创建日志文件的各种方法 - 也通过策略)。
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." />
查看升级表,结果如下:
测试用例:使用透明铝作为测试项目,您可以尝试此过程以使升级工作:
- 将产品代码设置为
*
以便为每个构建 ("<Product Id="*" ..."
) 自动生成一个新的 ProductCode。 - 编译您的 MSI 的第一个版本。在解决方案视图中右键单击 WiX 项目,
Visual Studio
然后选择Open Folder in File Explorer
. 进入bin
和Debug
或Release
。 - 通过在文件名末尾添加 _1 来重命名已编译的 MSI。例如:MySetup_1.msi
- 现在增加 WiX 源中产品版本字段的前 3 位数字之一:
<Product Id="*" ... Version="2.0.0"
- 编译一个新的 MSI 并重命名它:MySetup_2.msi
- 从版本 1 开始安装 MSI 文件,然后安装第二个。验证主要升级是否成功。
高级:这是一个使用便利元素"MajorUpgrade"
和旧"Upgrade"
元素的组合配置主要升级的高级方法的演示(允许您对生成的升级表进行更细粒度的控制):
以下是仅使用较旧的升级元素导致更多工作的示例,但对升级表的完全控制:主要升级 - “旧的手动方式”。
链接:
推荐阅读
- java - 我根据用户从 Excel 表中选择的浏览器并行进行跨浏览器测试的方法是否正确?
- java - 在 TestNG 中运行包时出现 java.lang.NullPointerException
- powershell - 如何过滤掉内置和不需要的组(Where-Object PS)
- python - 如何将文件夹中的所有文件作为输入(一次一个)并在处理后将它们保存到另一个文件夹中?
- go - 使用管道的 Redis 客户端计数
- javascript - 如何在 .test.js 中模拟 firebase .auth().currentUser
- c++ - 将 std::forward 用于未进一步传递给函数的通用引用是否有意义?
- javascript - cloneNode without losing event listener
- css - 对称形式
- css - 反应 ChakraUI ForwardRef 孩子忽略变体道具