为了克服 ICE,您应该将每用户注册表移至单独的组件,并使用某些注册表项作为该组件的 keyPath,即:
<Component Id='PerUserRegistry' Guid='*'>
<RegistryValue Id="PerUserRegistry_KeyPAth" KeyPath="yes" Root="HKCU" Key="Software\[Manufacturer]\[ProductName]\[ProductCode]\PerUserRegistry" Name="[PackageCode]" Value="[ProductVersion]" Type="string" />
<!--Other Per-user registry goes here-->
</Component>
我完全同意 Christopher 的观点:在卸载时保留每个用户的数据是常见的做法,但如果需要删除,那么 Active Setup 是唯一真正的选择。
首先,我建议您在安装或重新安装时删除它们而不是卸载,您只需要添加RemoveRegirty条目和Active Setup,即使用以下WiX代码:
<Component Id='ActiveSetup' Guid='*'>
<RegistryValue Id="ActiveSetup00" Root="HKLM" KeyPath="yes" Key="SOFTWARE\SOFTWARE\Microsoft\Active Setup\Installed Components\[PackageCode]\" Name="StubPath" Value="msiexec /fup [ProductCode] /qb-!" Type="string" />
<RegistryValue Id="ActiveSetup01" Root="HKLM" Key="SOFTWARE\SOFTWARE\Microsoft\Active Setup\Installed Components\[PackageCode]\" Value="[ProductName] [ProductVerion] Configuration" Type="string" />
</Component>
<Component Id='PerUserRegistryCleanup' Guid='*'>
<RegistryValue Id="PerUserRegistry_KeyPath" Root="HKCU" KeyPath="yes" Key="SOFTWARE\SOFTWARE\Microsoft\Active Setup\Installed Components\[PackageCode]\" Name="StubPath" Value="msiexec /fup [ProductCode] /qb-!" Type="string" />
<RemoveRegistryKey Id='PerUserRegCleanup' Root='HKCU' Action='removeOnInstall' Key='Key\To\Be\Removed'/>
</Component>
注意:强烈建议在 ActiveSetup 中使用 [PackageCode],因此对于 MSI 包的每个新版本(构建),您都需要添加单独的条目(另请参阅我的最后注释)。我故意使用每用户主动安装注册表作为密钥路径,因此您不会为当前用户运行它两次。
至于卸载后删除它们,
现在,希望您需要删除整个键,而不仅仅是某些值。在任何一种情况下,我都会创建自定义操作以在卸载期间添加活动安装程序的注册表条目(或者如果有许多此类键/值,请使用这些键/值创建和部署 .CMD 文件,并在卸载时启动它,然后在删除文件操作之前添加所有其中到注册表)。
注意:我强烈建议在安装过程中添加删除此注册表,否则您可能最终会在安装软件时删除每个用户的值。
这是所有这些的 WiX 代码:
<CustomAction Id="CA_UninstallRegistryCleanUp" Directory="SystemFolder" ExeCommand="REG.exe ADD "HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\MySoftName_CleanUp" /v StubPath /d "reg add ^"HKCU\Key\To\Be\Removed^" /va /f" /f" Return="ignore" />
<InstallExecuteSequence>
<Custom Action='CA_UninstallRegistryCleanUp' After='RemoveRegistryValues'>REMOVE~="ALL"</Custom>
</InstallExecuteSequence>
<Component Id='RegCleanup_Remover' Guid='*'>
<RegistryValue Id="PerUserRegistry_KeyPAth" Root="HKLM" KeyPath="yes" Key="SOFTWARE\[Manufacturer]\[ProductName]\[ProductCode]\" Name="DummyKey" Value="[ProductVersion]" Type="string" />
<RemoveRegistryKey Id='RegCleanup_Remover' Root='HKLM' Action='removeOnInstall' Key='SOFTWARE\Microsoft\Active Setup\Installed Components\MySoftName_CleanUp'/>
</Component>
最后注意事项:
所有这些主动安装的东西只有两个小问题:在 Windows 终端服务器上要小心;一旦为当前 .MSI 的一个用户运行了主动安装,如果您决定重新安装相同的软件包,它将不会再次运行,除非您更改其 PackageConde 或在 ActiveSetup 注册表项下提升版本。这些是改天的主题,如果需要澄清,请告诉我。
并且不要忘记将上述所有组件添加到某些功能中。