Simple .Net Bootstrapper

Feb 23, 2015 at 9:06 AM
Hi there, I've been trying for quite some time to get a simple .Net-Bootstrapper to work.
The Bootstrapper should determine if .Net 4.5 is installed and install it in case it's not installed yet and then install my product. My product installer has a custom WPF-UI.
To properly determine the .Net version I need to evaluate a specific registry key:
using (var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"))
{
if (key == null)
{
    return false;
}
int releaseKey = Convert.ToInt32(key.GetValue("Release"));
return releaseKey >= 378389;
}

So I want to check the registry (in a custom action I guess), execute the .Net 4.5 web installer (http://go.microsoft.com/fwlink/?LinkId=397707) which I downloaded as an exe-file, in case .Net 4.5 is not present on the target machine and then run my product installer.
The sample code doesn't help enough. i tried it with the "Simplified Bootstrapper" but keep getting "No CA or UI entry points found in module". I'd be very gratefull if you could point me in the right direction or provde a link with an exmaple.
Coordinator
Feb 24, 2015 at 1:57 AM
Please find the code skeleton of the potential solution here: https://dl.dropboxusercontent.com/u/2192462/Support/Crazychief/Bootstrapper.7z
Feb 24, 2015 at 4:32 AM
Hi Oleg,
thank you very much for the immediate response. I've been working with this sample and always keep getting the following error message:
Searching for custom action entry points in setup.cs.dll
Searching for an embedded UI class in setup.cs.dll
Error: No CA or UI entry points found in module: ...\setup.cs.dll
Error: Specified file could not be executed.

This is basically my setup.cs-code:
static public void Main(string[] args)
{
Project project = new Project(ProductName,
    new Dir(ProductPath, new WixSharp.File("MyProduct.exe")),
        new Binary("NET45.exe"),
        new ManagedAction(@"InstallNETAction", 
                            Return.check, 
                            When.Before, 
                            Step.LaunchConditions,
                            Condition.NOT_Installed,
                            Sequence.InstallUISequence));

project.UI = WUI.WixUI_InstallDir;
project.GUID = new Guid("...");
project.Version = new Version("1.1.1.0");
project.MajorUpgradeStrategy = MajorUpgradeStrategy.Default;
project.AddRemoveProgramsIcon = "Icon.ico";

Compiler.BuildMsi(project);
}

[CustomAction]
public static ActionResult InstallNETAction(Session session)
{
if (!IsNETInstalled())
{
    var netExeFile = Path.ChangeExtension(Path.GetTempFileName(), ".exe");
    SaveBinaryToFile(session, "NET45.exe".Expand(), netExeFile);

    //install NET
    Process.Start(netExeFile).WaitForExit();

    if (!IsNETInstalled())
    {
        var result = MessageBox.Show(".NET 4.5 is not installed.\n\nDo you want to continue without .NET 4.5?", "Prerequisites is not found", MessageBoxButtons.YesNo);

        if (result == DialogResult.No)
            return ActionResult.UserExit;
    }
}

return ActionResult.Success;
}

static bool IsNETInstalled()
{
using (var key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
{
    if (key == null)
    {
        return false;
    }
    int releaseKey = Convert.ToInt32(key.GetValue("Release"));
    return releaseKey >= 378389;
}
}

I'm using a custom WPF-UI. Could the exception I'm getting be related to that custom UI?
Coordinator
Feb 24, 2015 at 7:46 AM
Before we proceed can you tell me if you
  • can compile the SimplifiedBootstrepper sample?
  • can compile the code sample I shared with you?
Coordinator
Feb 25, 2015 at 12:29 AM
Sorry, I am off now. Will be able to discuss further in 2 weeks.
Feb 26, 2015 at 11:49 AM
Hi, sorry for the delayed answer. Yes I can compile both examples. I can send you the project if you want to try it out. Just tell me where to.
Coordinator
Mar 13, 2015 at 12:45 AM
OK I am back. :)
You can share the project on Dropbox(or similar)and just post the link here.
Alternatively you can use "support" email from here: http://www.csscript.net/wixsharp.html
Mar 17, 2015 at 8:32 AM
Edited Mar 17, 2015 at 10:51 AM
Hi Oleg,

hope you had a great vacation ;)
You can find a sample project here: https://www.dropbox.com/s/emrndazy7ab7zm4/MyApplication.Setup.zip?dl=0

It's a WPF-Project that doesn't contain the setup.cs as a project file. The setup.cs-file is located within the "Installer"-folder. (For my convenience I added an external command to my Visual Studio that enables me to run "cmd"-files from within VS. That's the way I use the "BuildMSI.cmd" file.)

If you run the BuildMSI.cmd you should see the exception mentioned above.

Thanks again for taking your time for this one!
Coordinator
Apr 1, 2015 at 7:05 AM
Sorry, only now I has some time to look at your project.
I cannot load it into VS (some problems with references) but it doesn't matter because the problem is in the building the msi with BuildMSI.cmd.

WiX MakeSfxCA.exe reports the following error (consistent with your description):
_Searching for custom action entry points in setup.cs.dll
Searching for an embedded UI class in setup.cs.dll
Error: No CA or UI entry points found in module: ...\setup.cs.dll
Error: Specified file could not be executed.

This means that the it cannot find a method marked with the 'CustomAction' attribute as an entry point. Your setup.cs indicates that it has to be 'InstallNETAction' method. But problem is that its class (Script) is private. Unfortunately MakeSfxCA.exe doesn't report the problem accurately. To fix this problem it is enough to to declare Script as public.

The next version of Wix# will do extra validation to provide some extra info on MakeSfxCA failure.
Apr 1, 2015 at 9:42 AM
Hi Oleg,

that's it. Adding the "public" solved the problem. The MSI is built now. Will let you know if the bootstrapping works as expected as soon as I have time to try it out ;)
Thank you very much!