
Including one component or another depending on the condition
An installer should be able to adapt to its surroundings, to mold itself to the operating system or other constraints it detects. WiX has this sort of intelligence baked in. By using conditions, we can prevent a component from being installed if it's not a good fit and simultaneously allow a different component to be installed.
In this recipe, we'll store two XML files in the MSI and select only one of them to install based on the target operating system. We'll be using a built-in property called VersionNT
to get the operating system, but this can be extended by defining our own custom properties. For example, you might install a component if the user selects Yes
for a radio button in the user interface. Or, you might install debug versions of your DLLs depending on whether you're installing to a development machine.
Getting ready
To prepare for this recipe, perform the following steps:
- Create a setup project and name it
ConditionalComponentsInstaller
. - Add an XML file to the project and call it
Windows7.xml
. - Add a second XML file and call it
Windows8.xml
.
How to do it…
Add a Condition
element to Component
to install it only if the condition is true
, such as if the version of Windows matches our expectation:
- Add a
Component
for each XML file:<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> <Component Id="cmpWindows7XML" Guid="{1FDA4A47-B45B-4040-A486-56EDA4B036B8}"> <File Source="Windows7.xml" /> </Component> <Component Id="cmpWindows8XML" Guid="{2FF087CE-9483-4456-BF77-FB1F6D700A76}"> <File Source="Windows8.xml" /> </Component> </ComponentGroup>
- Add the
Condition
elements inside each component. Use the predefinedVersionNT
property to check the version of Windows that's installed. For Windows 7, the value of this property will be automatically set to601
. For Windows 8, it will be602
:<Component Id="cmpWindows7XML" Guid="{1FDA4A47-B45B-4040-A486-56EDA4B036B8}"> <File Source="Windows7.xml" /> <Condition>VersionNT = 601</Condition> </Component> <Component Id="cmpWindows8XML" Guid="{2FF087CE-9483-4456-BF77-FB1F6D700A76}"> <File Source="Windows8.xml" /> <Condition>VersionNT = 602</Condition> </Component>
How it works…
In this recipe, we're installing two XML files. However, the first will only be installed if the operating system is Windows 7 and the second only if it's Windows 8. We started by adding components in the way that we always have. The trick was to add the Condition
elements to each, comparing a property called VersionNT
to a number that represents a version of Windows.
The VersionNT
property is built into Windows Installer without you having to set it. Each version of Windows gets a number that we can compare with this property to see which operating system we're dealing with. Specific values for VersionNT
can be found on Microsoft's MSDN website at http://msdn.microsoft.com/en-us/library/aa370556(v=vs.85).aspx. You might not find Windows 8.1 in the list, since it's so new, but its value is 603
. Other built-in properties can be found at http://msdn.microsoft.com/en-us/library/aa370905(v=vs.85).aspx.
We used an equals sign (=
) to do a comparison:
<Condition>VersionNT = 601</Condition>
We could have checked for any operating system greater than Windows 7 by using the greater-than-or-equal-to operator (>=
), such as:
<Condition>VersionNT >= 601</Condition>
Similarly, we could have checked whether the operating system was Windows 7 or older by using the less-than-or-equal-to operator (<=
):
<Condition><![CDATA[VersionNT <= 601]]></Condition>
In this case, we had to surround the statement with the CDATA
tags so that our less-than sign wouldn't be confused with the surrounding XML. We can also combine two expressions to see if the operating system falls within a range, such as Windows 7 through Windows 8.1 inclusive:
<Condition> <![CDATA[VersionNT >= 601 AND VersionNT <= 603]]> </Condition>
There's more…
The Component
element has an attribute called Transitive
that, when set to yes
, will cause any Condition
within the Component
to be re-evaluated if the installer is rerun, as shown in the following code:
<Component Id="cmpWindows7XML" Guid="{1FDA4A47-B45B-4040-A486-56EDA4B036B8}" Transitive="yes">
Here, if the child Condition
evaluates to false the second time around, the component will be removed from the end user's computer. Alternatively, if the condition evaluates to true, the component will be installed even if it hadn't been before.