In Part 1, we looked at the steps required to create a Windows Installer using Wix that dynamically packages the binaries from a target .NET application ready for deployment. In this part, we'll look at adding some condition checks into the installer that prevents a user from installing the software unless some conditions are met.
In our solution, we will create condition checks for the following:
- Install only on Windows 7
- Install only if the Microsoft .NET Framework 4 Client Profile is installed
- Install only on Dell hardware
Wix provides a variety of ways to add condition checks using registry or file system searches for example. When a condition element is added as a child node of the
Project element, it will only allow installation when the condition is met. If not, the installation will be terminated with the given error message.
Windows 7 Condition
To add a condition that prevents users from installing the application on versions of Windows other than Windows 7, we can leverage some existing properties populated by Windows Installer. These are the
WindowsBuild properties. If we look at the documentation for Operating System Property Values, we find that the required values for detecting Windows 7 are VersionNT 601 and WindowsBuild greater than 7100.
To implement the condition, we add the following element into the Main.wxs file within the
<Condition Message='[ProductName] can only be installed on Windows 7' >
VersionNT = 601 AND WindowsBuild >
The result is that the installer will now only install the application on devices running Windows 7, otherwise an error is thrown and the installation is terminated.
Microsoft .NET Framework 4 Client Profile Condition
The WixNetFxExtension.dll extension used in Part 1 provides a set of useful utilities related to the .NET Framework and this includes properties that can be used for detecting the version of the .NET Framework that is currently installed.
Unfortunately, version 3.0 of the framework doesn't include a property for detecting .NET 4.0 and this will only be available in Wix 3.5. Luckily, detecting if a particular version of the framework is installed isn't too difficult, and we can use a simple registry search as follows:
Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client"
This populates a property named
NETFRAMEWORK40CLIENT with a value of
1 if the registry key is found. Using this, we can then implement the condition check. We skip the condition check on uninstall in case the framework is subsequently removed.
<Condition Message="[ProductName] requires the Microsoft .NET Framework 4 Client Profile">
Installed Or NETFRAMEWORK40CLIENT
Dell Hardware Condition
To implement a hardware check, we need to perform a WMI lookup to determine the hardware manufacturer. To get the WMI value into Windows Installer so that we can implement a condition, we need to use a custom action.
There are a variety of ways to implement a custom action. For simplicity in this case, we will use an embedded VBScript called WMIQuery.vbs. The script will perform the WMI lookup and poke this into the installer as a property named
To begin, we add a reference to the WMIQuery.vbs file using a
Binary element. We then define a custom action that will invoke a function within the script and schedule this to run after
AppSearch in the
InstallUISequence sequences. This makes the property available prior to running the condition checks during install.
The new code looks something like this:
<Condition Message='This application cannot be installed on this hardware.'>
<CustomAction Id="WMIQuery" Return="check" BinaryKey="WMIQuery" VBScriptCall="Main" />
<Binary Id="WMIQuery" SourceFile="Binary\WMIQuery.vbs" />
<Custom Action="WMIQuery" After="AppSearch" />
<Custom Action="WMIQuery" After="AppSearch" />
Note the use of the contains
>< for the condition check. The operator characters must be escaped within
CDATA blocks to prevent validation issues with the XML. We have also added an override property called
SKIPCHECK that will allow us to override the hardware condition when run from the command line for testing. To do this, we execute the MSI as follows:
msiexec /i setup.msi SKIPCHECK=1
So far in this series, we have looked at creating a Windows Installer using Wix which dynamically packages a .NET application and applies NGen against the assemblies during installation. We have now also added some conditions to prevent the application being installed in specific scenarios using a range of techniques. In Part 3, we will look at localizing the installer and providing auto-language detection using the user's region settings.
- 22nd August, 2010: Initial post
Mike Carlisle - Technical Architect with over 20 years experience in a wide range of technologies.