WiX 3.8:使用相同注册表值的两个MSI。如果同时卸载两个MSI,如何删除注册表值?

问题描述 投票:1回答:1

我有两个MSI应用程序(app1.msi和app2.msi)共享同一组注册表值。两个MSI都引用了一个包含所有自定义操作和内容的dll。我正在使用WiX 3.8。这些注册表值是解决方案的自定义。

我需要找到卸载过程的方法,只有在删除两个应用程序时才删除注册表值。现在,每当我删除app1或app2时,删除注册表值,除非我卸载并重新安装,否则其他应用程序将无法使用。

关于如何解决这个问题的任何想法?

c# wix windows-installer registry
1个回答
4
投票

这是一个非常常见的问题。问题是你的MSI设置都认为他们“拥有”有问题的文件和注册表项,所以他们很乐意在卸载时删除它们 - 这显然很明显。现在该怎么办呢?

解决方案通常是使用相同的组件GUID在两个设置中安装注册表项/文件。实际上,这意味着组件被注册为共享组件。 MSI的内置机制是“merge modules”(你可以build merge modules with WiX)。您还应该能够使用WiX包含文件 - 但我必须承认我从未花时间去实际尝试它。基本上这需要将一个组件放入一个Wi​​X源文件中,然后由两个设置包含,如下所示(使用WiX中的预处理器功能):How to include wxi file into wxs?

在两个MSI文件中使用相同的组件GUID后,在安装两个产品时,它的引用计数将为2。卸载一个产品时,引用计数将减少为1,因此不会卸载该组件。卸载第二个产品后,一旦达到0,它将被卸载(除非它被标记为永久组件)。

了解组件引用计数是理解MSI的关键。这里有一个答案,如果你花时间仔细阅读它可能有所帮助(我想我推荐这个 - 请给它一次性):Change my component GUID in wix?(请阅读这个答案,看看它是否仍然有意义)。


现在进一步的复杂化:“在野外”部署旧的MSI文件意味着从现在开始设置稳定的组件GUID不一定有助于解决问题,因为在安装新的MSI时卸载旧的MSI仍然认为它在卸载时“拥有”注册表项 - 因此将删除它。只有当您的设置“知道”该组件​​已共享且其注册表项应保持不变时,才能解决该问题。

在我详细说明之前,这些MSI文件是否存在?正如在野外发表,还是你还在发展中?

为了超越自己:如果你可以改变注册表项的位置(例如从HKLM\Software\Company\MyProductHKLM\Software\Company\NewProduct - 这通常是不可能的),然后还为它设置一个新的组件GUID,那么你应该“去耦合”从过去的罪过和你的新MSI文件应该正确共享组件。


尽管如此,我想问一下这些注册机构设置是在HKCU还是在HKLM?通常不建议将设置写入HKCU表单MSI设置 - 您应该在首次启动应用程序时填充HKCU。这种方法可以解决许多难以部署的问题 - 或者防止它们存在。

© www.soinside.com 2019 - 2024. All rights reserved.