简体   繁体   English

WiX 3.8:两个MSI使用相同的注册表值。 仅在两个MSI都卸载的情况下才如何删除注册表值?

[英]WiX 3.8: Two MSI using the same registry values. How to delete registry values only if both MSI are uninstalled?

I have two MSI applications ( app1.msi and app2.msi ) that share the same set of registry values. 我有两个MSI应用程序( app1.msiapp2.msi ),它们共享同一组注册表值。 Both MSI are referencing a dll which contains all custom actions and stuff. 两个MSI都引用一个包含所有自定义操作和内容的dll。 I am using WiX 3.8. 我正在使用WiX 3.8。 These registry values are custom for the solution. 这些注册表值是针对解决方案定制的。

I need to find a way for the uninstall process to ONLY remove the registry values if both applications are removed. 我需要找到一种卸载过程,仅在删除了两个应用程序的情况下才删除注册表值。 Right now, whenever I remove either app1 or app2 the registry values are removed, leaving the other application unusable unless I uninstall and re-install. 现在,每当我删除app1app2时 ,注册表值都会被删除,除非卸载并重新安装,否则其他应用程序将无法使用。

Any ideas as to how to solve this problem? 关于如何解决这个问题有什么想法吗?

This is a very common question. 这是一个非常普遍的问题。 The problem is that both your MSI setups think they "own" the file and registry keys in question so they happily remove them on uninstall - this is obviously clear. 问题在于,您的MSI安装程序都认为它们“拥有”相关的文件和注册表项,因此它们在卸载时会很乐意将其删除-这很明显。 Now what to do about it? 现在该怎么办?

The solution is generally to use the same component GUID to install the registry keys / file in both setups. 解决方案通常是在两个设置中使用相同的组件GUID安装注册表项/文件。 Effectively this means that the component is registered as a shared component. 实际上,这意味着该组件已注册为共享组件。 MSI's built-in mechanism to do this is " merge modules " (you can build merge modules with WiX ). MSI的内置机制是“ 合并模块 ”(您可以使用WiX构建合并模块 )。 You should also be able to use WiX include files - though I have to admit that I have never taken the time to actually try it. 您还应该能够使用WiX包含文件-尽管我必须承认我从未花时间进行实际尝试。 Essentially this would entail putting a single component in a WiX source file that is then included by both setups, something like this (using the preprocessor feature in WiX): How to include wxi file into wxs? 从本质上讲,这将需要将单个组件放入WiX源文件中,然后将其同时包含在两个设置中,如下所示(使用WiX中的预处理器功能): 如何将wxi文件包含到wxs中? .

Once the same component GUID is used in both MSI file, the reference count for it will be 2 when both products are installed. 一旦在两个MSI文件中使用了相同的组件GUID,则在安装两个产品时,该文件的引用计数将为2。 When one product is uninstalled the reference count will be reduced to 1 and the component will hence not be uninstalled. 卸载一种产品后,引用计数将减少为1,因此该组件将不会被卸载。 Once it reaches 0 when the second product is uninstalled, it will be uninstalled (unless it is marked as a permanent component). 卸载第二个产品时,一旦达到0,它将被卸载(除非将其标记为永久组件)。

Understanding component reference counting is key to understanding MSI. 了解组件引用计数是了解MSI的关键。 There is an answer here that might help if you take the time to read it thoroughly (I think I recommend this - please give it a once-over): Change my component GUID in wix? 这里有一个答案,如果您花时间仔细阅读它,可能会有所帮助(我想我建议您-请给它一次以上的说明): 在wix中更改组件GUID吗? (please do read this answer, see if it still makes sense). (请务必阅读此答案,看看是否仍然有意义)。


And now a further complication: having deployed your old MSI files "in the wild" means that setting a stable component GUID from now on will not necessarily help to sort out the problem since your old MSI being uninstalled as you install your new MSI still thinks it "owns" the registry key when it is being uninstalled - and hence will delete it. 现在又变得更加复杂:“在野外”部署旧的MSI文件意味着从现在开始设置稳定的组件GUID并不一定有助于解决问题,因为在安装新MSI时卸载了旧的MSI仍然认为它在卸载时“拥有”注册表项-因此将其删除。 The problem is only solved when both your setups "know" that the component is shared and its registry keys should be left alone. 仅当您的设置都“知道”该组件​​已共享并且其注册表项应单独放置时,才能解决该问题。

Before I elaborate this, are these MSI file live? 在我详细说明之前,这些MSI文件是实时的吗? As in published in the wild, or are you still in development? 就像在野外出版一样,还是您还在开发中?

To get ahead of myself: if you can change the location of the registry key (For example from HKLM\\Software\\Company\\MyProduct to HKLM\\Software\\Company\\NewProduct - which is usually not possible) and then also set a new component GUID for it, then you should be "de-coupled" from the sins of the past and your new MSI files should share the component properly. 超越自我:如果您可以更改注册表项的位置(例如,从HKLM\\Software\\Company\\MyProduct更改为HKLM\\Software\\Company\\NewProduct通常是不可能的),然后还设置一个新组件GUID为此,您应该与过去的罪恶“脱钩”,新的MSI文件应正确共享组件。


With all that being said, I want to ask if these registry settings are in HKCU or in HKLM? 话虽如此,我想问一下这些注册表设置是在HKCU还是HKLM中? It is generally not recommended to write settings to HKCU form MSI setups - you should rather populate HKCU when your application is first launched. 通常不建议将设置写入HKCU形式的MSI设置-您应该在首次启动应用程序时填充HKCU。 This approach can solve a lot of hard deployment problems - or prevent them from ever existing. 这种方法可以解决很多硬部署问题-或防止它们永远存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM