【问题标题】:WIX does not uninstall older versionWIX 不会卸载旧版本
【发布时间】:2019-07-11 13:02:53
【问题描述】:

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

我的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)

【问题讨论】:

    标签: wix windows-installer


    【解决方案1】:

    日志记录:要正确调试失败的主要升级,您需要 create a proper log file(创建日志文件的各种方法 - 也符合政策)。

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

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


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

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

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

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


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


    可能的原因:对主要升级失败的许多可能原因的简要总结。

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

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

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

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

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

    • 悬空版本:也有可能您的 WiX 标记没有问题,并且您有一个从未正确配置的悬空旧版本,如果是这样,请手动卸载它并再试一次或尝试一个干净的虚拟。如果您 auto-generate the product GUID 未正确设置主要升级,您最终可能会同时安装多个版本的产品。

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

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

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

    更多细节:需要记住的更多事项:

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

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

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

    WiX 学习曲线:建议使用一些样本来帮助加快学习过程。唯一真正有用的是什么? Here are some WiX Quick Start Suggestions。里面有示例链接。

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

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

    查看产生的Upgrade table

    测试用例:使用透明铝材作为测试项目,您可以尝试这个程序来进行升级:

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

    高级:这里演示了使用便利元素 "MajorUpgrade" 和较旧的 "Upgrade" 元素(允许您对生成的升级表进行更细粒度的控制):

    Adding entries to MSI UpgradeTable to remove related products

    这里是一个示例,它只使用旧的升级元素导致更多的工作,但对升级表的完全控制:Major Upgrade - "The Old, Manual Way"


    链接

    【讨论】:

    • 我从这个复制和粘贴狂欢中得到的是,第四位的版本更改不算数。对吗?
    • 那是正确的,that is stated in the MSI SDK documentation(你读过它还问吗?)。另外:答案也是为其他人编写的 - 用于通用重用。改写以前写过的东西是一种练习和实验,看看是否可以做得更好。
    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 2014-06-03
    • 2012-03-30
    • 2013-02-17
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    相关资源
    最近更新 更多