WiX Burn - Determine what items are already installed

六月ゝ 毕业季﹏ 提交于 2019-12-09 05:36:36

问题


I've a burn installation whereby the user can select which of three options to install - each one directly relates to one of three MsiPackages in a chain, such as :

<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>

All fine. However, when I run the msi next time, I only want to re-install/update the items that were selected originally - ie if only productA was selected, I don't want to install products B & C.

How do I determine what was originally selected?


回答1:


OK, Sorted it, so I'd best post my solution.

Ultimately it boils down to two parts...

a) setting a registry key in each of the Product MSI's which are set on installation. Obviously if that MSI was not installed originally, then the registry entry will not exist. i.e.

  <!-- 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) Checking for the existence of that registry key in burn when doing the upgrade...

<!-- 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>

So in the InstallCondition, chkProductA evaluates to true when the UI is used and the respective checkbox is checked, and ProductAInstalled evaluates to true when the respective product has already been installed - taking care of the update which in my case happens without any user interaction.

Easy when you know how. I certainly didn't to start with...




回答2:


If you are doing your own managed bootstrapper application, you can do this in a DetectPackageComplete event handler:

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

A similar thing can be done to detect installed features using DetectMsiFeature.

That being said, I would only use this method if you already have a custom BA. Building a custom BA is a lot of work.



来源:https://stackoverflow.com/questions/12917287/wix-burn-determine-what-items-are-already-installed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!