Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio
All postings are provided AS IS with no warranties, and confer no rights. Additionally, views expressed herein are my own and not those of my employer, Microsoft.
Question:
I have an application that requires the .NET Framework 2.0 SP2. I would like to author a condition in my MSI-based installer to check for SP2 or higher so that the application will continue to install even if future service packs are released for the .NET Framework 2.0.
What is the correct way to check for the .NET Framework 2.0 SP2 or greater in an MSI-based installer?
Answer:
The following registry value that can be used to detect the service pack level for the .NET Framework 2.0 on a system:
[HKEY_LOCAL_MACHINE\Software\Microsoft\NET Framework Setup\NDP\v2.0.50727] SP
This SP registry value is a DWORD registry value. That means you can author a Windows Installer registry locator to retrieve the SP registry value during your application's installer. In WiX v3.0, the syntax looks like the following:
<Property Id="NETFRAMEWORK20_SP_LEVEL" Secure="yes"> <RegistrySearch Id="NetFramework20SP" Root="HKLM" Key="Software\Microsoft\NET Framework Setup\NDP\v2.0.50727" Name="SP" Type="raw" /> </Property>
Note - instead of defining the above registry locator in your setup authoring, you can include the following PropertyRef that is a part of the WixNetFxExtension in WiX v3.0:
<PropertyRef Id="NETFRAMEWORK20_SP_LEVEL" />
When querying this registry value in your MSI, the property value NETFRAMEWORK20_SP_LEVEL will be set to blank if the registry value does not exist on the system. It will be set to a value like "#0" or "#1" or "#2" depending on the exact service pack level on the system.
It will be tempting to simply check that NETFRAMEWORK20_SP_LEVEL >= "#2" in your MSI in order to verify that the .NET Framework 2.0 SP2 or later is installed. However, it is very important to note that this property value will be set to a string value and not a numerical value. That means that when you do comparisons in an MSI launch condition or custom action, you must use string comparison logic or else you run the risk of incorrectly detecting the service pack level on a user's system. The place where this causes the most problems is when the value goes from a single digit to double digits. For example, service pack 10 is greater than service pack 2, but the string value "#10" is less than the string value "#2". This means you cannot just check to make sure that the NETFRAMEWORK20_SP_LEVEL property is greater than or equal to "#2" to correctly detect service pack 2 or greater.
Because a string comparison can lead to incorrect results, I suggest that your MSI instead check individual values to narrow down the service pack level. For example, to verify that the system has service pack 2 or greater, you can make sure that the SP registry value exists and that it does not equal 0 or 1.
Implementing a launch condition to perform the check
The following WiX v3.0 syntax can be used to implement a Windows Installer launch condition that checks for the .NET Framework 2.0 SP2 or greater:
<PropertyRef Id="NETFRAMEWORK20_SP_LEVEL" /> <Condition Message="[ProductName] requires .NET Framework 2.0 SP2 or higher (Launch Condition). Setup will now exit."> <![CDATA[(NETFRAMEWORK20_SP_LEVEL AND NOT NETFRAMEWORK20_SP_LEVEL = "#0" AND NOT NETFRAMEWORK20_SP_LEVEL = "#1") OR Installed]]> </Condition>
<Condition Message="[ProductName] requires .NET Framework 2.0 SP2 or higher (Launch Condition). Setup will now exit."> <![CDATA[(NETFRAMEWORK20_SP_LEVEL AND NOT NETFRAMEWORK20_SP_LEVEL = "#0" AND NOT NETFRAMEWORK20_SP_LEVEL = "#1") OR Installed]]> </Condition>
Implementing a type 19 custom action to perform the check
When I create MSI-based installers, I prefer to use type 19 custom actions instead of launch conditions for this type of prerequisite checking because you can control the order in which the prerequisite checks are performed when using custom actions, but you cannot control the order when using launch conditions. The following WiX v3.0 syntax can be used to implement the same check for the .NET Framework 2.0 SP2 or greater as shown above with a custom action instead of a launch condition:
<PropertyRef Id="NETFRAMEWORK20_SP_LEVEL" /> <CustomAction Id="CA_CheckForNetfx20Sp2OrGreater" Error="[ProductName] requires .NET Framework 2.0 SP2 or higher. Setup will now exit." /> <InstallExecuteSequence> <LaunchConditions After="AppSearch"/> <Custom Action="CA_CheckForNetfx20Sp2OrGreater" After="LaunchConditions">(NOT NETFRAMEWORK20_SP_LEVEL OR NETFRAMEWORK20_SP_LEVEL = "#0" OR NETFRAMEWORK20_SP_LEVEL = "#1") AND NOT Installed</Custom> </InstallExecuteSequence> <InstallUISequence> <LaunchConditions After="AppSearch"/> <Custom Action="CA_CheckForNetfx20Sp2OrGreater" After="LaunchConditions">(NOT NETFRAMEWORK20_SP_LEVEL OR NETFRAMEWORK20_SP_LEVEL = "#0" OR NETFRAMEWORK20_SP_LEVEL = "#1") AND NOT Installed</Custom> </InstallUISequence>
<CustomAction Id="CA_CheckForNetfx20Sp2OrGreater" Error="[ProductName] requires .NET Framework 2.0 SP2 or higher. Setup will now exit." />
<InstallExecuteSequence> <LaunchConditions After="AppSearch"/> <Custom Action="CA_CheckForNetfx20Sp2OrGreater" After="LaunchConditions">(NOT NETFRAMEWORK20_SP_LEVEL OR NETFRAMEWORK20_SP_LEVEL = "#0" OR NETFRAMEWORK20_SP_LEVEL = "#1") AND NOT Installed</Custom> </InstallExecuteSequence>
<InstallUISequence> <LaunchConditions After="AppSearch"/> <Custom Action="CA_CheckForNetfx20Sp2OrGreater" After="LaunchConditions">(NOT NETFRAMEWORK20_SP_LEVEL OR NETFRAMEWORK20_SP_LEVEL = "#0" OR NETFRAMEWORK20_SP_LEVEL = "#1") AND NOT Installed</Custom> </InstallUISequence>
I have also created a full set of sample files that can be used to build an MSI using WiX v3.0 that includes a custom action to check for the .NET Framework 2.0 SP2 or later and block installation if it is not present. You can find the sample files at http://astebner.sts.winisp.net/Tools/WiX%20Samples/wix_sample_detect_netfx_sp_level.zip. To build this sample, you need to do the following:
Additional notes:
This di not work for me !
I did just that, but somehow when .net framework 3.5 was installed it still gave the message.
I delever my code:
<Property Id="NETFRAMEWORK20_SP_LEVEL" Secure="yes">
<RegistrySearch Id="NetFramework20SP" Root="HKLM" Key="Software\Microsoft\NET Framework Setup\NDP\v2.0.50727" Name="SP" Type="raw" />
</Property>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<Condition Message="[ProductName] requires .NET Framework 2.0 SP2 or higher (Launch Condition). Setup will now exit."><![CDATA[(NETFRAMEWORK20_SP_LEVEL AND NOT NETFRAMEWORK20_SP_LEVEL = "#0" AND NOT NETFRAMEWORK20_SP_LEVEL = "#1") OR Installed]]></Condition>
Did I miss something?
at the end I used MsiNetAssemblySupport condition here: http://n2.nabble.com/Launch-condition-for-checking-.net-framework.-td2311214.html
Hi Michallush - Does the system you're running this installation on actually have 2.0 SP2 on it? Can you try to manually check the registry value and see what is listed there? The reason I ask is that the .NET Framework 3.5 installs 2.0 SP1 behind the scenes, not 2.0 SP2. You only get 2.0 SP2 if you install 3.5 SP1.