8

我有一个刻录安装,用户可以选择安装三个选项中的哪一个 - 每个选项都直接与链中的三个 MsiPackage 之一相关,例如:

<Chain>
  <MsiPackage SourceFile="..\ProductA\bin\Release\ProductA.msi"  InstallCondition="chkProductA" />
  <MsiPackage SourceFile="..\ProductB\bin\Release\ProductB.msi"  InstallCondition="chkProductA" />
  <MsiPackage SourceFile="..\ProductC\bin\Release\ProductC.msi"  InstallCondition="chkProductC" />
</Chain>

一切都好。但是,当我下次运行 msi 时,我只想重新安装/更新最初选择的项目 - 即如果只选择了 productA,我不想安装产品 B 和 C。

如何确定最初选择的内容?

4

2 回答 2

10

好的,已排序,所以我最好发布我的解决方案。

最终归结为两部分...

a) 在安装时设置的每个产品 MSI 中设置一个注册表项。显然,如果最初没有安装该 MSI,则注册表项将不存在。IE

  <!-- registry entry to state that the item has been installed-->
  <Component Id="cmp_WriteToRegistry" Guid="[yourguid]">
    <RegistryKey Root="HKLM"
                 Key="Software\MyCompany]"
          Action="createAndRemoveOnUninstall">
      <RegistryValue Type="integer" Name="ProductA" Value="1" KeyPath="yes"/>
    </RegistryKey>
  </Component>

b)在升级时检查该注册表项是否存在...

<!-- Determine what items are to be installed in the event of an install using the BA-->
<WixVariable Id="chkProductA" Value="![CDATA[chkProductA]]" />
<WixVariable Id="chkProductB" Value="![CDATA[chkProductB]]" />
<WixVariable Id="chkProductC" Value="![CDATA[chkProductC]]" />

<!-- Determine what items are installed in the event of an upgrade-->
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\MyCompany" Value="ProductAInstalled" Variable="ProductAInstalled" Result="exists" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\MyCompany" Value="ProductBInstalled" Variable="ProductBInstalled" Result="exists" />
<util:RegistrySearch Root="HKLM" Key="SOFTWARE\MyCompany" Value="ProductCInstalled" Variable="ProductCInstalled" Result="exists" />

<Chain>
  <MsiPackage SourceFile="..\SetupProductA\bin\Release\SetupProductA.msi"
              InstallCondition="chkProductA OR ProductAInstalled" />
  <MsiPackage SourceFile="..\SetupProductB\bin\Release\SetupProductB.msi"
              InstallCondition="(chkProductB) OR (ProductBInstalled)" />
  <MsiPackage SourceFile="..\SetupProductC\bin\Release\SetupProductC.msi"
              InstallCondition="(chkProductC) OR (ProductCInstalled)" />
</Chain>

</Bundle>

因此,在 InstallCondition 中,当使用 UI 并选中相应的复选框时,chkProductA 的评估结果为 true,而当相应的产品已经安装时,ProductAInstalled 的评估结果为 true - 处理在我的情况下无需任何用户交互的情况下发生的更新。

当你知道怎么做时很容易。我当然不是一开始...

于 2012-10-19T13:38:56.143 回答
3

如果您正在执行自己的托管引导程序应用程序,则可以在 DetectPackageComplete 事件处理程序中执行此操作:

CustomBA_DetectPackageComplete(object sender, DetectPackageCompleteEventArgs e)
{
    if (e.PackageId == "SetupProductA" && e.State == PackageState.Present)
    {
        CustomBA.Engine.NumericVariables["chkProductA"] = 1;
    }
    etc...
}

可以使用类似的方法来检测已安装的功能DetectMsiFeature

话虽如此,如果您已经拥有自定义 BA,我只会使用此方法。构建自定义 BA 需要大量工作。

于 2013-08-30T17:04:29.133 回答