Using custom actions versus using launch conditions in an MSI

I ran into an interesting issue when I was working on some of the very early builds of the Windows Media Center SDK for Windows Vista. A customer reported that they tried to install the SDK on Windows Vista and it blocked them and reported an error stating that the product could not be installed because it requires the .NET Framework 2.0. This error message was particularly confusing because the .NET Framework 2.0 is included as part of the OS on Windows Vista, so there is no way for it to not be present in this customer's scenario.

When I investigated this issue in more detail, I found that the user was trying to install the SDK when logged in as a normal user (as opposed to a user that was a member of the Administrators group on the computer). That was the first clue that led to figuring out the root cause of the inaccurate error message.

In early builds, the SDK setup contained 2 entries in the LaunchCondition table:

  1. A check for the Privileged property to validate that the user running setup has administrative privileges
  2. A check of the .NET Framework 2.0 detection registry hive to verify that the .NET Framework 2.0 is installed on the system

The problem in this scenario was that the launch condition to check for the .NET Framework 2.0 was running before the check for administrative privileges. Because that check needed to access a registry value under HKEY_LOCAL_MACHINE, it failed if the user running setup did not have administrative privileges, and setup would block with an error stating that the .NET Framework 2.0 was not installed. It never got the chance to check for administrative privileges.

I did some research and asked some friends I know who have worked with Windows Installer pretty extensively, and I found that there are not any reliable ways to control the order in which the entries in the LaunchCondition table of the MSI are executed. Because of this, many setups choose to use custom actions to validate prerequisites instead of launch conditions.

In the end, I solved this issue by creating a type 19 custom action to check for the presence of the .NET Framework 2.0. By using a custom action instead of a launch condition, I was able to control the exact execution order by placing it in the desired sequential order in the InstallUISequence and InstallExecuteSequence tables of the MSI.

You can see an example of how to use this prerequisite checking strategy with an MSI built with the WiX toolset in this example WXS file I previously posted about the .NET Framework 2.0 configuration tool.