4

我目前正在维护一个具有大量用户定义的注册表项的软件。我正在尝试制作一个 WIX 安装程序,以使这些注册表项保持最少的可维护性。我决定将注册表项中的每个值都设为它自己的组件,以允许我使用 WIX 的 NeverOverwrite='yes' 功能。我假设它的存在将允许进行较小的升级(例如 REINSTALL=ALL REINSTALLMODE=vomus)来创建值(如果存在),否则不要理会它。但是,在我的真实示例中,这似乎并没有发生(功能上没有条件)。文档告诉我我应该很好。以下是一些示例:

<Product Id="UNIQUE_KEY" Name="Spotbox Manager" Language="1033" Version="1.0.1.0"    Manufacturer="Company"  UpgradeCode="MY_UPGRADE_KEY">
<Package  Platform="x64" Id="*" InstallerVersion="200" Compressed="yes"    InstallScope="perMachine" InstallPrivileges="elevated" />
<Upgrade Id="MY_UPGRADE_KEY">
  <UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
    Minimum='1.0.1' IncludeMinimum='yes'
    Maximum='1.0.1' IncludeMaximum='yes' />
  <UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
    Minimum='1.0.1' IncludeMinimum='no' />
</Upgrade>

这是注册表项的实际片段

<Component Id="cmp171812fcc51a4b91ad386fa8c27c9b89" Directory="TARGETDIR" Guid="COMPONENT_GUID"  Win64='yes' NeverOverwrite='yes'>
  <RegistryKey Key="SOFTWARE\Company" Root="HKLM">
    <RegistryValue Name="Value" Value="1100797834" Type="integer" KeyPath='yes'/>
  </RegistryKey>
</Component>
<Component Id="cmp211639bff9694f029028a22cb0bb9687" Directory="TARGETDIR" Guid="NEW COMPONENT GUID"  Win64='yes' NeverOverwrite='yes'>
  <RegistryKey Key="SOFTWARE\Company" Root="HKLM">
    <RegistryValue Name="Country Code" Value="1" Type="integer" KeyPath='yes' />
  </RegistryKey>
</Component> ...

请注意:两个值的密钥相同 当我尝试更改它时,这似乎仍然会吹走用户的价值。

4

2 回答 2

1

首先,在同一个注册表项下拥有多个值并将它们用作单独的键路径是没有问题的。术语“keypath”与注册表术语无关,在注册表的情况下,它实际上必须标识一个值而不是键。

其次,您的评论提到在小升级期间不会发生产品卸载。这在产品级别上是正确的,但在组件级别上是不正确的。

您应该检查您是否未在产品的新旧版本之间更改行为不端组件的 GUID 或键路径 - 如果您这样做了,您显然违反了小升级(组件删除)的规则。但是,即使您的 GUID 稳定,请继续阅读,我会为您提供更通用的解释。

次要更新是重新安装。我正在想象以下事件顺序。

  1. (CostFinalize) Windows Installer 检查是否已经安装了与 keypath 相同的组件(不是由用户重写或删除),因此不必安装;根据NeverOverwrite启用)。
  2. (InstallExecute) Windows Installer 从旧的 MSI 卸载组件,因为该组件将被新的 MSI 替换(由次要更新规则保证);根据Permanent旧包中的禁用。
  3. (InstallExecute) Windows Installer 会记住步骤 1 中的检查,并且不关心使用相同的密钥路径安装不同的组件。

你至少有这些修正选项,选择一个。

  • 进行重大升级。这几乎总是更容易和更好的选择。
  • Permanent除了 之外启用NeverOverwrite,假设您可以在所有版本中这样做;基本上,你还没有发布任何确定的东西。大多数人保持这些属性同步,所以为什么不随波逐流并减少问题。
  • 弄乱动作的顺序。例子:

    <RemoveExistingProducts After="InstallValidate"/>

最后一个选项会使您的升级变慢,但如果您真的想要小升级并利用NeverOverwrite没有Permanent.

于 2013-03-23T21:50:26.417 回答
0

我发现问题是用户错误我在注册表中有太多值,以至于我没有注意到另一个类似但没有组件元素的部分(旧配置)。在我删除它之后,一切都按预期工作。谢谢你们的帮助。

于 2013-03-25T17:29:00.197 回答