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 4 and type the answer here:
  • Post
  • $(var.TestUX.TargetDir) is undefined.  Where is supposed to come from?

  • @Ken, the sample authoring is not buildable by itself. It's merely an example of what the authoring looks like, and would require the complete solution to be buildable.

    I recommend installing WiX 3.6 and take a look at the src\Setup for a complete example (in the form of the WiX bundle itself).

  • Unfortunately src\Setup does not exist in my wix 3.6 install.  I need a complete example.

    You suggested to @Patel that http://wixtoolset.org contains samples of bootstrapper applications.  I have looked but not found it there either.  Could you please provide a more specific link.

  • @Ken, installing WiX is necessary to build. You can download the sources from the same site which will have the src\Setup directory.

  • do i compile that stuff with candle?

  • Please FTLOG release some tutorials for wpf user interface installers... I have been searching for days wasted only to find 2 random mvvm based incomplete examples and the source code in wix source files not easy to follow so complex... can we get a straight forward basic example that can be made complicated by people that implement it not the training and documentation? Please :)

    Seriously though this is not a rant... Wix is very great I am just tired of wasting tmy time trying to make a simple interface to improve our installation experience :) I would think this would be one of your latest greatest wants from the project.

  • @alex, yes. You build a bundle like you'd build an MSI package. Run candle.exe to get the .wixobj, then pass the .wixobj (and any other .wixobj or .wixlib files you want to link in) to light.exe.

  • Hello Heath,

    In Wix 3.6, the following bootstrapper.wxs used to display "Our Product Patch 2" in the bootstrapper dialog title:

    <Wix xmlns="schemas.microsoft.com/.../wi">

    <Bundle Version="1.1.1" >

    <Variable Name='BundleName' Value='Our Product Patch 2' />

    <WixVariable Id="WixStdbaLicenseRtf" Value="eula.rtf" />

    <WixVariable Id="WixStdbaLogo" Value="Logo.bmp" />

    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />

    <Chain>

    <MspPackage PerMachine="yes" SourceFile="media\Patch2.msp" />

    </Chain>

    </Bundle>

    </Wix>

    As of Wix 3.7, it doesn't show up in the title. Instead, it only shows "Setup".

    If I add to "Bundle" element, such as,

    <Bundle Name='Our Product Patch 2' ...

    then it appears not only in the title but also in Add/Remove Program (ARP). We don't want it to appear in ARP.

    Is this regression or something I miss?

    Thank you in advance.

  • @Klee, for WiX support please see http://wixtoolset.org.

  • I am newbie for bootStrapper. i went through your tutorial it looks more simpler so i tried it with my own simple project. but i stuck when generated exe file doesn't started. i have posted this issue in detail on stackover flow too. here is the link.  

    stackoverflow.com/.../setup-created-by-wix-bootstrapper-is-not-started

    please help me out.

  • @Ramesh, support for WiX can be found appropriately on http://wixtoolset.org.

  • In regards to the Burn BA supporting silent installs, is it possible yet to run the wrapper/bootstrapper silently but have the msi's in the bundle display their UI?  I know I can pass the command to have the various exe's and msi's run silently inside of the bootstrapper, but what about the reverse?  

  • @Stu, if you write your own BA you could, but why would you want to? I can't imagine any scenario that WiX would want to support with wixstdba to do this. But you can always ask via http://wixtoolset.org.

  • Great post, thank you very much.

    I got two question after reading:

    1)

    How to set the Version from the bundle? We call the compilation from msbuild like this:

    <Exec Command="$(MSBuildBinPath)\OurSLNWithBundleAndBootstrapper.sln /p:Configuration=Release;DefineConstants="PRODUCTVERSION=$(Number)" />

    In the bundle we have this piece of xml:

    <Bundle Name="OurName" Version="$(var.PRODUCTVERSION)" ..... />

    We always got a compiler warning: ->  The parameter to the compiler is invalid, '/define:PRODUCTVERSION=1.0.5581.55386' will be ignored.  I can't figure out whats wrong with this. The same way works fine for the setup project itself.

    1) Parallel installation

    This question may sounds a bit strange, but our customer needs this feature. We want to offer parallel installation of our product when the product code of the internal msi is not equal to that one which is already installed. These different versions are incompatible, so we would change all guids then.

    The DetectPackageComplete-Event seems only to parse names of the msi, but not their code.

    Any help is appreciated :-)

    Kind regards,

    Torben

  • Third try to leave a post ;-)

    Great post, thank you very much.

    I got two question after reading:

    1)

    How to set the Version from the bundle? We call the compilation from msbuild like this:

    <Exec Command="$(MSBuildBinPath)\OurSLNWithBundleAndBootstrapper.sln /p:Configuration=Release;DefineConstants="PRODUCTVERSION=$(Number)" />

    In the bundle we have this piece of xml:

    <Bundle Name="OurName" Version="$(var.PRODUCTVERSION)" ..... />

    We always got a compiler warning: ->  The parameter to the compiler is invalid, '/define:PRODUCTVERSION=1.0.5581.55386' will be ignored.  I can't figure out whats wrong with this. The same way works fine for the setup project itself.

    1) Parallel installation

    This question may sounds a bit strange, but our customer needs this feature. We want to offer parallel installation of our product when the product code of the internal msi is not equal to that one which is already installed. These different versions are incompatible, so we would change all guids then.

    The DetectPackageComplete-Event seems only to parse names of the msi, but not their code.

    Any help is appreciated :-)

    Kind regards,

    Torben

Page 2 of 3 (31 items) 123