Conditional Properties

In this tutorial I want you to show, how the WiX Toolset makes it possible to set properties dependent on given conditions.

Why would you want to do that?
In my usecase it is part of the continous delivery, where I want the setup to set different registry keys (e.g. connectionstrings), depending on the environment it is installed.
Fortunatly each server in our infrastructure has an environment-variable set, which is called ENV. The values of it can be DEV/TEST/PROD.

How does it work
Unfortunatly it is not as straightforward as you might think, as it involves three steps.

  1. Define custom-actions for properties (where you’ll set the values per condition):
    <CustomAction Id="TEST_MyConnectionStringAction" Property="CONFIGPROPERTY_MYCONNECTIONSTRING" Value="HereWouldBeTheTestConnectionString" />
    <CustomAction Id="PROD_MyConnectionStringAction" Property="CONFIGPROPERTY_MYCONNECTIONSTRING" Value="HereWouldBeTheProdConnectionString" />
    
  2. Execute the customaction if the condition is fulfilled. As you see the condition must be formulated in a somewhat wierd way. You can find more about it on the Microsoft Conditional Statement Syntax Page and on the belonging Example page.
    <InstallExecuteSequence>
    	<Custom Action="TEST_MyConnectionStringAction" Before="InstallFiles"><![CDATA[%ENV="TEST"]]></Custom>
    	<Custom Action="PROD_MyConnectionStringAction" Before="InstallFiles"><![CDATA[%ENV="PROD"]]></Custom>
    </InstallExecuteSequence>
    
  3. Use the property (in the registrykey in our example):
    <RegistryKey Root="HKLM" Key="SOFTWARE\YourSoftware">
    	<RegistryValue Type="string" Name="MyConnectionStringRegistryKey" Value="[CONFIGPROPERTY_MYCONNECTIONSTRING]" KeyPath="yes"/>
    </RegistryKey>
    

The full example
As it can be difficult to figure out, which piece belongs on which place, I show you the complete example here. Please note, that the example is for a 64bit operating-system.

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product Id="*" Name="SetupTestProject" Language="1033" Version="1.0.0.0" Manufacturer="YourCompany" UpgradeCode="ed935467-2b3c-4249-a99a-fea346bdebf5">
		<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platform="x64" />

		<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
		<MediaTemplate />

		<!-- Property-Action Definition-->
		<CustomAction Id="TEST_MyConnectionStringAction" Property="CONFIGPROPERTY_MYCONNECTIONSTRING" Value="HereWouldBeTheTestConnectionString" />
		<CustomAction Id="PROD_MyConnectionStringAction" Property="CONFIGPROPERTY_MYCONNECTIONSTRING" Value="HereWouldBeTheProdConnectionString" />
    
		<!-- Conditionally execute the property actions -->
		<InstallExecuteSequence>
			<Custom Action="TEST_MyConnectionStringAction" Before="InstallFiles"><![CDATA[%ENV="TEST"]]></Custom>
			<Custom Action="PROD_MyConnectionStringAction" Before="InstallFiles"><![CDATA[%ENV="PROD"]]></Custom>
		</InstallExecuteSequence>
  
		<Feature Id="ProductFeature" Title="SetupTestProject" Level="1">
			<ComponentGroupRef Id="ProductComponents" />
		</Feature>
	</Product>

	<Fragment>
		<Directory Id="TARGETDIR" Name="SourceDir">
			<Directory Id="ProgramFiles64Folder">
				<Directory Id="INSTALLFOLDER" Name="SetupTestProject" />
			</Directory>
		</Directory>
	</Fragment>

	<Fragment>
		<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
			<Component Id="ProductComponent" Win64="yes">
				<!-- The registrykeyvalue is set with the CONFIGPROPERTY_MYCONNECTIONSTRING property -->
				<RegistryKey Root="HKLM" Key="SOFTWARE\YourSoftware">
					<RegistryValue Type="string" Name="MyConnectionStringRegistryKey" Value="[CONFIGPROPERTY_MYCONNECTIONSTRING]" KeyPath="yes"/>
				</RegistryKey>
			</Component>
		</ComponentGroup>
	</Fragment>
</Wix>