Mailbag: How can I detect the presence of the .NET Framework 2.0 or later in my MSI-based installer?

Question:

I am creating an application that is built on the .NET Framework 2.0, and I am attempting to create an MSI-based installer for it.  I have seen documentation and sample code describing how to detect the presence of individual versions of the .NET Framework.  My application does not require a specific version of the .NET Framework, but has a minimum version of 2.0, so I would like to detect the presence of the .NET Framework 2.0 or later in order to try to avoid needing to update my installation logic each time the .NET Framework ships a new version.  How can I do this?

Answer:

There is not an officially supported way of checking for the presence of a range of .NET Framework versions.  There are supported ways of checking for each version that has been released, but this logic can only be used to determine whether or not that exact version is installed.  This logic cannot necessarily be used to infer anything about other versions of the .NET Framework.  In particular, it is not possible to know ahead of time what types of detection logic will be needed for versions of the .NET Framework that have not yet been released.

As a result, it is most reliable to have your application's installer check for specific versions of the .NET Framework that you have tested your application against and that you know your application is compatible with.  Then, you can update your installer logic if you need to support additional versions of the .NET Framework as they are released in the future.

Admittedly, it is not ideal to have to update your installer as new versions of the .NET Framework are released, but it is the only way to be sure that your detection logic will return the correct result for .NET Framework install state checks in the future.  As a side benefit, the process of updating your installer will also help ensure that you perform the necessary compatibility testing to ensure that your application continues to work as expected when installed on a system that only has some future version of the .NET Framework that was not available to test against when your application originally shipped.

For reference, here are a few ways that I have seen various setups use in order to attempt to implement a "greater than or equal" check for versions of the .NET Framework along with reasons why they are not reliable:

  • Check for the presence of the .NET Framework 2.0 using the documented detection registry value in order to detect the .NET Framework 2.0 or higher.  This check happens to work for the .NET Framework 3.0 and 3.5 because 3.0 and 3.5 are not truly new versions of the .NET Framework (meaning - they do not update the underlying CLR), and 3.0 and 3.5 both require 2.0 to be installed before they allow the user to install.  However, this logic is not necessarily going to be true in future versions of the .NET Framework and there will likely eventually be a new version of the CLR that will cause this type of check to return incorrect results on a system that does not also have the .NET Framework 2.0 installed.
  • Check the value of the Windows Installer MsiNetAssemblySupport property.  This property is set to the version number of fusion.dll for the latest version of the CLR that is installed on the system.  This property does not get updated to a version greater than 2.0 when installing the .NET Framework 3.0 or 3.5 because both 3.0 and 3.5 use the 2.0 version of the CLR.  As a result, this property cannot currently be used to distinguish any versions of the .NET Framework greater than 2.0.  In addition, using this property may also not return the correct installation state needed for your application if the .NET Framework client profile is installed on the system but a full version of the .NET Framework is not installed.  For example, if your application requires a part of the .NET Framework not included in the client profile, but you use the MsiNetAssemblySupport property to detect the .NET Framework, it may return true when in reality the full version of the .NET Framework needed by your application is not present on the system.
  • Check the version number of %windir%\system32\mscoree.dll.  This file is shared by all versions of the CLR and will have a file version equal to the highest installed version of the CLR on the system.  This file will still have a 2.0 version after installing the .NET Framework 3.0 or 3.5 because both 3.0 and 3.5 use the 2.0 version of the CLR.  As a result, this file cannot currently be used to distinguish any versions of the .NET Framework greater than 2.0.  In addition, using this file may also not return the correct installation state needed for your application if the .NET Framework client profile is installed on the system but a full version of the .NET Framework is not installed.  For example, if your application requires a part of the .NET Framework not included in the client profile, but you use the file version of mscoree.dll to detect the .NET Framework, it may return true when in reality the full version of the .NET Framework needed by your application is not present on the system.

A note for WiX users

If you are using WiX v3.0 to create MSI-based installers, there are some built-in properties in the WixNetFxExtension that can be included in your setup authoring to detect the presence of all currently released versions of the .NET Framework.  You can find a how-to help topic describing how to check for versions of the .NET Framework in an MSI-based setup using WiX v3.0 in builds 3.0.4220.0 or higher of WiX v3.0.  You can download WiX builds at https://wix.sourceforge.net/releases.  In the table of contents in WiX.chm (which is located in wix3-binaries.zip for each build of WiX), the topic is located under WiX Help | How To Guides | Redistributables and Install Checks | How To: Check for .NET Framework Versions.