bsara
bsara

Reputation: 8249

WiX Extended Bootstrapper Application: How to determine which radio button is selected?

Here's my setup:

So I'm creating a bootstrapper installation project and though I've got it working, I feel like there is a much more clean and easy way to do it.

Basically, I need to have the user select which environment they wish to use when they install the product. To do this, I use the WiX Extended Bootstrapper Application extension to allow me to put some radio buttons on the first install screen.

Getting that all setup was fine, but then I realized that I don't know how to easily determine which radio button has been selected. So as I work around I just listed the MSI three times in the bundle and put install conditions on each one.

Is there a way to determine which radio button has been selected with just one property? (For example, when I pass the InstallFolder property to my MSI as seen in the code below.) And if there isn't a way to do this currently, is there a way for me to do this without adding my MSI three times to the bundle?

Here's my code (Notice how I list essentially the same MsiPackage three times):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <?include Properties.wxi ?>

  <Bundle Name="!(loc.Product.Name)" Version="$(var.Version)" Manufacturer="!(loc.Product.Manufacturer)" UpgradeCode="$(var.UpgradeCode)" Condition="VersionNT >= v5.1">
    <BootstrapperApplicationRef Id="WixExtendedBootstrapperApplication.Hyperlink2License">
      <bal:WixExtendedBootstrapperApplication SuppressRepair="yes" LicenseUrl="" ThemeFile="$(var.Bundle.ExtTheme.RadioBtns.Path)" LocalizationFile="$(var.Bundle.ExtTheme.RadioBtns.l10n.Path)" />
    </BootstrapperApplicationRef>

    <WixVariable Id="WixMbaPrereqPackageId" Value="Netfx4Full" />

    <Variable Name="InstallFolder" Type="string" Value="$(var.InstallFolder.Value)" />

    <Variable Name="RadioButton1" Type="numeric" Value="0" />
    <Variable Name="RadioButton2" Type="numeric" Value="0" />
    <Variable Name="RadioButton3" Type="numeric" Value="1" />

    <Chain>
      <!-- Other Package References Here -->

      <MsiPackage Id="DBConnections_Dev"
                  SourceFile="$(var.MSI.Path)"
                  Visible="no"
                  Vital="yes"
                  InstallCondition="RadioButton1 = 1">
        <MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
        <MsiProperty Name="SELECTED_ENV" Value="1" />
      </MsiPackage>
      <MsiPackage Id="DBConnections_Stage"
                  SourceFile="$(var.MSI.Path)"
                  Visible="no"
                  Vital="yes"
                  InstallCondition="RadioButton2 = 1">
        <MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
        <MsiProperty Name="SELECTED_ENV" Value="2" />
      </MsiPackage>
      <MsiPackage Id="DBConnections_Prod"
                  SourceFile="$(var.MSI.Path)"
                  Visible="no"
                  Vital="yes"
                  InstallCondition="RadioButton3 = 1">
        <MsiProperty Name="INSTALLFOLDER" Value="[InstallFolder]" />
        <MsiProperty Name="SELECTED_ENV" Value="3" />
      </MsiPackage>
    </Chain>
  </Bundle>
</Wix>

Upvotes: 0

Views: 3923

Answers (1)

bsara
bsara

Reputation: 8249

I also asked this question on the project's CodePlex site and the developer responded as follows (here is a link to the full discussion: http://wixextba.codeplex.com/discussions/432341):

This can now be done using the custom actions feature.

I've tested his response and found it to be correct! This functionality is available as of version 3.7.4791.32058. There is also an example included in the source code demonstrating how this is done. I've posted the pertinent code below:

Needed in Custom Action c++ code:

STDMETHODIMP OnPlanCustomAction()
{
  ...
  if (SUCCEEDED(BalGetNumericVariable(L"RadioButton1", &llValue)) && llValue)
  {
    m_pEngine->SetVariableNumeric(L"RadioButton", 1);
    BalExitOnFailure(hr, "Failed to set variable.");
  }
  else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton2", &llValue)) && llValue)
  {
    m_pEngine->SetVariableNumeric(L"RadioButton", 2);
    BalExitOnFailure(hr, "Failed to set variable.");
  }
  else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton3", &llValue)) && llValue)
  {
    m_pEngine->SetVariableNumeric(L"RadioButton", 3);
    BalExitOnFailure(hr, "Failed to set variable.");
  }
  else if (SUCCEEDED(BalGetNumericVariable(L"RadioButton4", &llValue)) && llValue)
  {
    m_pEngine->SetVariableNumeric(L"RadioButton", 4);
    BalExitOnFailure(hr, "Failed to set variable.");
  }
  else
  {
    m_pEngine->SetVariableNumeric(L"RadioButton", 0);
    BalExitOnFailure(hr, "Failed to set variable.");
  }
  ...


Needed in WiX XML (from examples that come with downloaded DLL):

<Variable Name="RadioButton1" Type="numeric" Value="0" />
<Variable Name="RadioButton2" Type="numeric" Value="1" />
<Variable Name="RadioButton3" Type="numeric" Value="0" />
<Variable Name="RadioButton4" Type="numeric" Value="0" />

<Chain DisableSystemRestore="yes">
  <PackageGroupRef Id="NetFx40Redist" />
  <MsiPackage
    Id="Setup"
    Compressed="yes"
    SourceFile="Setup.msi"
    Vital="yes">
    <MsiProperty Name="APPLICATIONFOLDER" Value="[InstallFolder]" />
    <MsiProperty Name="RadioButton" Value="[RadioButton]" />
  </MsiPackage>
</Chain>

Check out the links in the text for the original examples from which these code samples were taken. Hope this helps others in the future.

Upvotes: 1

Related Questions