在安装和维护期间在组件之间切换

Switch between components during installation and maintenance

我正在使用 WiX 为 Windows 服务构建一个合并模块。 合并模块的工作不仅是安装文件,而且还进行一些配置如果用户在设置过程中选择了这个选项(带有一些表单字段和复选框的单独对话框)。其余设置是使用 InstallShield 构建的。

为此,我有两个组成部分。第一个基本上只是写一个注册表项。另一个配置并启动服务,它的关键路径是一个(不同的)注册表项。

工作起来非常棒,直到我 运行 测试了两次安装程序。弹出 InstallShield 维护对话框,我可以 select 修改安装。我的期望是我可以通过更改是否满足相反条件的组件来在我的两个组件之间切换($(var.ValidConfiguration) 在 WiX 文件中的某处定义,整个事物都有括号):

没有配置的组件:

  <Component Id="ServiceConfigurationDisabled" Guid="(some guid)" Transitive="yes">
    <Condition><![CDATA[NOT $(var.ValidConfiguration)]]></Condition>
    <ServiceControl
      Id="DontStartService" Name="MyService"
      Stop="both" Remove="both" Wait="no" />

    <!-- Registry entry without value, is key path -->
    <RegistryValue
      Root="HKLM" Key="SOFTWARE\Company\MyService)"
      Name="AutoconfigDisabled" Value=""
      Type="string" KeyPath="yes" />
  </Component>

具有配置的组件:

  <Component Id="ServiceConfigurationEnabled" Guid="(different guid)" Transitive="yes">
    <Condition><![CDATA[$(var.ValidConfiguration)]]></Condition>
    <ServiceControl
      Id="StartService" Name="MyService"
      Start="install" Stop="both" Remove="both" Wait="no" />

    <!-- Other registry entry, this time storing some information, is key path -->
    <RegistryValue
      Root="HKLM" Key="SOFTWARE\Company\MyService"
      Name="AutoconfigEnabled" Value="some value"
      Type="string" KeyPath="yes" />

    <!-- Other registry values, settings, ... -->
    <RegistryValue (...) />
    <util:XmlFile (...) />
    <firewall:FirewallException (...) />
  </Component>

第一次,我让条件评估为假。 日志文件在 InstallValidate 期间包含这些条目:

ServiceConfigurationDisabled.(guid); Installed: Absent;   Request: Local;   Action: Local
ServiceConfigurationEnabled.(guid); Installed: Absent;   Request: Local;   Action: Null

完美。 执行第二个组件的 None 个操作,仅创建 AutoconfigDisabled 注册表项。

再次调用设置,这次条件评估为真:

ServiceConfigurationDisabled.(guid); Installed: Local;   Request: Null;   Action: Null
ServiceConfigurationEnabled.(guid); Installed: Local;   Request: Null;   Action: Null

等等,什么?

即使在第一轮中没有安装第二个组件(这是Action: Null的意思?),它现在注册为Installed: Local。 None 执行了第二个组件的操作,注册表未更改。

我做错了什么?

在维护操作期间通常不会重新评估组件条件,因此它们不利于用户可能更改的内容。您可以通过在每个组件上设置 transitive attribute 来获得所需的行为,这会请求重新评估条件。但我怀疑您必须将组件分解为单独的合并模块,以便它们可以放置在使用项目中的单独功能上,然后专门为首次安装和维护选择这些功能。