0

我在 WiX 中有一个大程序,它使用了一堆 MSI、C# 自定义操作程序、UI、引导程序,你说它,它就在那里。

我遇到了这个问题:当我进行重大升级时,以前的版本没有被删除。也就是说,如果我从版本 1.0.0.x 升级到 1.1.0.x,程序和功能显示这两个版本都安装在机器上。

这是一个常见问题,在 SO 上有很多解决方案。他们都没有为我工作——如果有关于这个的帖子,我已经试过了。

有人告诉我,重大升级中的组件之间存在一对一的关系。也就是说,对于每个移除的组件,都必须添加另一个组件。当它不是一对一的关系时,旧版本没有被删除——因为仍然有旧组件挂起。

有没有办法确定哪些组件挂了?比如,在日志文件中还是什么?如果我能确定 MSI 有什么问题,我可以更积极主动地解决问题。


编辑:

虽然我还没有解决问题,但感谢厄尔曼先生的建议,我可能走上了正轨。

我创建了那个注册表项,但是......它似乎没有做任何事情。但是,我确实在我的卸载日志中搜索了“Disallow”这个词,我发现了这个短语 9 次:

Disallowing uninstallation of component: {GUID-HERE} since another client exists.

此外,此短语出现在“Disallow”短语的每个分组之前:

PROPERTY CHANGE: Adding INSTALLLEVEL property.  It's value is '1'.

这给了我一些东西可以继续。但是,我似乎找不到提到的 GUID!它们不在我的解决方案中,也不能在注册表中搜索。除了搜索注册表之外,有没有办法(Windows 7 32 位)找出特定 GUID 对应的组件?

4

1 回答 1

1

有人告诉我,重大升级中的组件之间存在一对一的关系。也就是说,对于每个移除的组件,都必须添加另一个组件。当它不是一对一的关系时,旧版本没有被删除——因为仍然有旧组件挂起。

严格来说,这不是真的。升级确实如此,并且在某些配置(涉及后期RemoveExistingProducts的配置)中,大升级同样挑剔。但是您典型的主要升级功能更像是用户选择卸载旧版本,然后安装新版本。首先验证您的假设:确保您进行了适当的主要升级(您更改了 ProductVersion 和 Product Code,并且在升级表中有正确的条目,对吗?)。然后诊断。

如何最好地识别正在发生的事情?以我的经验,日志文件是你最好的选择。由于旧版本被间接卸载,您不能使用命令行来记录它。因此,改为通过创建或设置以下注册表值来设置日志记录策略。(稍后当您想恢复设置时将其删除。)

HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer
值 (Reg_SZ):记录
数据:voicewarmup

然后运行您的主要升级,找到在%temp%中生成的相应日志文件。(考虑提前清除 %temp% 以便于查找。或按日期排序。)特别注意卸载(可以通过 ProductVersion 或 UPGRADINGPRODUCTCODE 的存在来识别)。我会特别寻找像Disallowing uninstallation of component ...这样包含组件 GUID 的行。

获得该 GUID 后,您必须弄清楚它是什么组件,以及它是如何进入当前状态的。您可以手动检查您构建的 .msi 文件(使用类似 Orca 的工具)来查找组件,但很少有工具会告诉您所有客户端。我雇主的产品带有一个名为 InstallShield Msi Sleuth 的帮助工具,它可以列出所有引用组件代码的已安装产品,或者您可以从MsiEnumProductsInstaller.ComponentClients构建自己的产品。您不能直接搜索注册表,因为 Windows Installer 以压缩或打包的形式存储 GUID。

然后确定“为什么”可能是困难的部分。或者它可能就像不正确的共享 DLL 引用计数一样简单,特别是如果您只是在测试机器上遇到过这种情况,而该测试机器已经看到了您的产品的非发布版本。

作为相关替代方案,但仅与小升级或小更新相关,您可以设置EnforceUpgradeComponentRules Policy。这有助于在您遇到问题时揭示问题,而不是让 Windows Installer 尽最大努力继续。

于 2017-09-07T12:36:17.343 回答