Introducing Managed Bootstrapper Applications

Introducing Managed Bootstrapper Applications

Rate This
  • Comments 31

Now that WiX v3.6 has been released, I introduce the managed bootstrapper application (MBA) interoperability layer. It’s been available for a while actually, and if you’ve installed any builds of WiX v3.6, or the Microsoft Visual Studio 11.0 Developer Preview you’ve seen it in action.

While Burn – the WiX bootstrapper engine – and the core bootstrapper application interfaces are native and allow you to develop completely native bootstrapper applications, MBA allows managed code developers to utilize their skills to develop rich interactive setups. WPF designers can also utilize their skills to make the setup UI look great. In fact, both of the setup applications mentioned above are written for WPF and running atop the MBA interop layer.

The MBA interop layer leverages COM interoperability features of the CLR, but without requiring previous registration of the assemblies as COM servers as in previous examples. The MBA interop layer is composed of both a native CLR host and the managed framework. It’s in this native CLR host that the managed framework assembly is loaded and COM interfaces marshaled as in-process pointers. Message passing is not required since the Burn engine is written as a free-threaded component. Once the managed framework assembly is loaded, a class factory will create the actual managed bootstrapper application authored in the configuration file and pass its IBootstrapperApplication interface pointers back to the engine.

Because MBA is managed, the .NET Framework is of course required. A simple native bootstrapper application (BA) written atop wixstdba is used to bootstrap the .NET Framework. When you use the WixBalExtension to author your MBA you define the WixMbaPrereqPackageId WixVariable to reference the package ID of the .NET Framework you want to install.

In the following example the .NET Framework 4.0 will be installed if required.

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
    <Bundle
        Name="Test" 
        Version="1.0.0.0" 
        IconSourceFile="Setup.ico">
        <BootstrapperApplicationRef 
            Id="ManagedBootstrapperApplicationHost">
            <Payload 
                Name="BootstrapperCore.config" 
                SourceFile="$(var.TestUX.TargetDir)\TestUX.BootstrapperCore.config"/>
            <Payload 
                SourceFile="$(var.TestUX.TargetPath)"/>
            <Payload 
                SourceFile="NetfxLicense.rtf"/>
        </BootstrapperApplicationRef>
        <Chain>
            <PackageGroupRef 
                Id="Netfx4Full"/>
            <MsiPackage 
                Compressed="yes" 
                SourceFile="$(var.TestPackage.TargetPath)" 
                Vital="yes">
                <MsiProperty 
                    Name="ARPSYSTEMCOMPONENT" 
                    Value="1"/>
            </MsiPackage>
        </Chain>
    </Bundle>
    <Fragment>
        <WixVariable 
            Id="WixMbaPrereqPackageId" 
            Value="Netfx4Full" />
        <WixVariable 
            Id="WixMbaPrereqLicenseUrl" 
            Value="NetfxLicense.rtf" />
 
        <util:RegistrySearch 
            Root="HKLM" 
            Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" 
            Value="Version" 
            Variable="Netfx4FullVersion" />
        <util:RegistrySearch 
            Root="HKLM" 
            Key="SOFTWARE\Microsoft\Net Framework Setup\NDP\v4\Full" 
            Value="Version" 
            Variable="Netfx4x64FullVersion" 
            Win64="yes" />
 
        <PackageGroup 
            Id="Netfx4Full">
            <ExePackage 
                Id="Netfx4Full" 
                Cache="no" 
                Compressed="no" 
                PerMachine="yes" 
                Permanent="yes" 
                Vital="yes" 
                SourceFile="dotNetFx40_Full_x86_x64.exe"
                DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=164193"
                DetectCondition="Netfx4FullVersion AND (NOT VersionNT64 OR Netfx4x64FullVersion)" />
        </PackageGroup>
    </Fragment>
</Wix>

You can customize this behavior even more. For example, since WPF was introduced in .NET 3.0, WiX supports a syntax similar to <supportedRuntime> in its own <wix.bootstrapper> section group: <supportedFramework>. This allows you to specify which Framework you require, inferring the CLR version.

<configuration>
    <configSections>
        <sectionGroup
            name="wix.bootstrapper"
            type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.BootstrapperSectionGroup, BootstrapperCore">
            <section 
                name="host" 
                type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.HostSection, BootstrapperCore" />
        </sectionGroup>
    </configSections>
    <wix.bootstrapper>
        <supportedFramework version="v4\Client" />
        <supportedFramework version="v3.5" />
        <supportedFramework version="v3.0" />
 
        <!-- Example only. Replace the host/@assemblyName attribute with 
        an assembly that implements BootstrapperApplication. -->
        <host assemblyName="AssemblyWithClassThatInheritsFromBootstrapperApplication" />
    </wix.bootstrapper>
</configuration>

Developers building atop MBA need to only reference the BootstrapperCore.dll assembly in the WiX binaries. We’re working on better documentation, but currently only IntelliSense is included. You can also look at the WiX v3.6 setup UI for an example.

I’ll be talking about the MBA interop layer and MBAs in general over the next few weeks.

Leave a Comment
  • Please add 6 and 7 and type the answer here:
  • Post
  • Great stuff, I have been forging ahead with creating an MBA (slowly) but I am looking forward to your future posts for help. Thanks!

  • The above "Netfx4FullVersion" will be "4.0.30319". In "ExePackage" element, how can I check if it is greater than or equal to "4.0.30319" in "DetectCondition"?

    I tried the following but it failed to handle the dots:

    <ExePackage ... DetectCondition="Netfx4FullVersion>=4.0.30319" />

  • @Klee, the condition syntax we designed includes version numbers as primitives. You need to put a "v" in from of that (like v4.0.30319) or surround the version in quotes (strings are coerced to versions if possible and comparing to a version variable).

  • Visual Studio 11 Developer Preview installer is so cool !!

    It there a way to access to the wix source/solution of it. Or a similar complete wix/wpf demo like you show here?

    I'm dying to update our product installer to wpf but with the wix doc right now I ain't going anywhere.

    Thank

  • @Julien, the source for the Visual Studio bootstrapper application (BA) is not available but you can find an example managed BA in teh current WiX 3.6 source. The BA for WiX 3.6 itself is managed and recently underwent a major overhaul that should serve as a better example.

  • Please tell more!  Unfortunately, it's taken me a few days to get a simple Burn application that just shows a message box with Command.Action.ToString().  I was working in vb.net, and didn't realize that I had to manually edit AssemblyInfo.vb to add

    Imports Microsoft.Tools.WindowsInstallerXml.Bootstrapper

    <Assembly: BootstrapperApplication(GetType(...))>

    It took just as much time figuring out that the .log coming out of Bootstrapper.exe ends up in

    C:\Users\<mylogin>\AppData\Local\Temp

    Now, I'm trying to figure out, how do I just tell the thing to just run the .msi's.  Trying to go through the WixBA application is at best frustrating, since I never worked with the ViewModel thing.  And, it looks like now I have to create my own dialogs for Install, Repair, Help, and everything else?!?

    If you look at the .msi dialogs, they have a big advantage; they work!  It takes a few small changes to insert or delete a dialog here or there, but the developer has a complete dialog set to change features, installation directories, etc.  Even the .BootstrapperProject has a very simple mechanism of adding very little XML to add pre-requisites such as .NET framework etc.  On the other hand, for Burn, I have to write detection mechanisms for something as simple as .NET framework, and I have to write a dialog to let the user select which Programs to install (equivalent to features in .msi) - seems not very developer friendly.

    So, it would be very nice if Burn was as easy to develop for as the .BootstrapperProject / .msi combo.  Maybe the Visual Studio folks are willing to share their Burn App dialogs?

  • @nick, thanks for your interest in the MBA. We've been busy with features so I've not had a lot of time to write up documentation, but given that WiX is open source and uses the MBA itself for the WiX36.exe installer, I encourage you to take a look at the source in src\Setup\WixBA. It's a WPF BA but shouldn't be hard to adapt for WinForms or whatever UI layer you want to use.

  • Hi Heath,

    I am struggling with getting the bootstrapper to work with a large installer. In my case, I have a WPF application that is the installer so the <ExePackage> element is what I need. But I need to install the .NET Framework first which is working but the remainder of the application has dependencies on a bunch of binaries and third-party tools. If I create <Payload> elements for all of them, then the install process is very slow as it takes time to copy all those files to the package cache location. Is there something I can do to cut out that process of just run the .exe from it original location rather than the package cache location?

    Thanks!

  • @Ricky, we copy to the cache directory because the installation media/source isn't always available. This has been a big cause of issues for Visual Studio setup and service packs, for example.

    But if the application requires those third-party tools, why aren't you installing them? Are they only setup dependencies? I highly recommend you remove external setup dependencies, statically linking when you can (for example, native custom actions) or just don't do whatever you're doing during setup. Setup is primarily about copying bits.

    More advanced configuration is typically best done by a configuration step sometime after setup and before first-use. Configuration utilities also have the advantage of letting the user re-configure the application to use different servers, paths to data files, etc. Microsoft has been moving in that direction for those reasons because advanced configuration during setup only causes problems.

  • I am totally new in this so can any one provide sample for this.. i am getting error in above code...

  • @Patel, the WiX source is provided from http://wixtoolset.org and contains samples of bootstrapper applications.

  • Allright how we can debugging managed bootstrapper application?

  • @Fatih, I use gflags.exe, which is part of the Debugger package from msdn.microsoft.com/.../gg463009.aspx. On the "Image" tab, type the name of the bundle EXE (just the file name and extension - not the path) then check "Debug" and type in your debugger of choice (I use vsjitdebugger.exe for VS). You are prompted to debug that EXE (either the initially elevated bundle or the bundle that also runs the BA - whichever you invoked first). Attach VS, load your project(s), set breakpoints, and hit F5. Then you're prompted for the other copy. Repeat the instructions above with another instance of VS. In some cases, I've had to set the debug project's debugger type to "Mixed" and restart this whole process (opening an existing instance of VS since you would leave the other two open).

    This probably would be a good blog post topic (or even walkthrough video) on its own. I'll add it to my backlog. Let me know if you have questions on what I wrote above, though, and I can clarify for now.

  • Does the wix source code contain some sample example of managed BA ? I need to create one with a custom UI.

  • @vivek, it sure does! :) The WiX setup BA itself is managed. See src\Setup\WixBA for the code. It supports silent and full UI modes, and even specifying an installation directory (though only on the command line right now).

Page 1 of 3 (31 items) 123