.net 4.5 prerequisite is not working properly (Wix# 1.0.16.0, WixTools 3.9)

May 1, 2015 at 1:43 PM
Edited May 1, 2015 at 1:46 PM
When I have enabled .net 4.5 framework prerequisite and test - my installer says than I should install .net 4.5. But I have installed .Net 4.5 framework on my machine.

I have doublechecked it with simple utility named ".NET Framework verification tool" by Aaron Stebner (Microsoft), his article and app link.

Probably it's not Wix#'s fault. Because .Net 4.0 prereq works well.
Coordinator
May 2, 2015 at 2:56 PM
I think I may just know the reason.

MSI is really inconsistent with the names and the values for the ".NET presence" properties.
For example for .NET4.0 the property value is expected to be "#1" and for .NET4.5 it has to be "1".

I had to change the semantics of SetNetFxPrerequisite. Now it takes a condition string instead of the property name:
project.SetNetFxPrerequisite("NETFRAMEWORK20='#1'", "Please install .NET 2.0 first.");
project.SetNetFxPrerequisite("NETFRAMEWORK30_SP_LEVEL and NOT NETFRAMEWORK30_SP_LEVEL='#0'", "Please install .NET 2.0 first.");
May 2, 2015 at 9:58 PM
Edited May 2, 2015 at 10:00 PM
I found a solution in case of using Wix# v 1.0.17.0.

First you need to read and understand very short and clear MSDN article named How to: Determine Which .NET Framework Versions Are Installed.

So, if you need to know if .Net Framework 4.5 is installed you can use this way:
project.SetNetFxPrerequisite("NETFRAMEWORK45 >= '#378389'", "Please install .Net 4.5 first");
So, magic number #378389 is a number of release value from windows registry (see short table in article). Code will detect .Net framework 4.5 version and higher and you don't need to check registry manually.

Hope this helps.
Marked as answer by office_rat on 5/2/2015 at 2:00 PM
Coordinator
May 3, 2015 at 6:06 AM
Great. I have reflected your findings on Wiki.
May 17, 2016 at 3:42 AM
Edited May 17, 2016 at 3:43 AM
With Wix# 1.0.36.2 and the following line in my project setup:
project.SetNetFxPrerequisite("NETFRAMEWORK45 >= '#378389'", "Please install .NET 4.5 first.");
I expected to get a "Please install .NET 4.5 first." message box prior to even running the UI (ManagedUI).

Instead, the installer goes through the whole UI, prompts for elevated privs, and then quickly fails with the following messages in the log:
ActionData: Property: NETFRAMEWORK45, Signature: NetFramework45
Info: Action ended 22:29:57: AppSearch. Return value 1.
ActionStart: Action 22:29:57: LaunchConditions. Evaluating launch conditions
Info: Action start 22:29:57: LaunchConditions.
Error: Please install .NET 4.5 first.
Is this by design?
Why is my error message coming out in the log and not as a popup message?
Why isn't the check happening before running the UI (and letting the user make many setup decisions which have no hope of installing)?

Tnx in advance :-)
Coordinator
May 18, 2016 at 5:08 AM
MSI way of checking prerequisites is not a direct one. It updates the certain session properties according the algorithm you specify (e.g. registry value). Then you need to schedule a special entity LaunchCondition and MSI takes care about prompting the user when it's required. Though MSI drops the 'user interaction' LaunchCondion part ("prompt message") if you are using custom UI (e.g. ManagedUI). That is why you don't have a message box while the LaunchCondition is evaluated.

It seems like a limitation but actually it is an advantage. If you are relying on MSI native UI you have no way of influencing how, when the prerequisites are checked and how they are communicated to the user. With ManagedUI you have everything under control.

In the setup events you can check the presence of .NET according dozens of algorithms. After that you can popup message box, open browser, shutdown setup...
You can do anything. You don't need to rely on MSI for that any more:
project.UILoaded += (s,e)=>
{
    if(e.IsInstalling && !IsDotNetPresent())
    {
        MessageBox.Show("Install .NET first");
        e.Result = ActionResult.Failure;
    }
}
Just remember that you will need to repeat the same for project.Load. Load is invoked always and UILoad only when UI is visible.

When checking the presence of .NET you can also utilize WixSharp.CommonTasks.Tasks.CurrentFrameworkDirectory, which is nothing else but a redirection to System.Runtime.InteropService.RuntimeEnvironment.GetRuntimeDirectory