rikuna
rikuna

Reputation: 13

Managed Bootstraper Application (for .Net Framework ) for Wix Toolset v4 Bundle

Been struggling for days to find a working example for a Managed BA for Wix Toolset v4. Most of them are in v3. I have exactly the same issue with this existing question here, and some similar questions too but without answer:

Wix Bundle Managed Bootstrapper Application - Error 0x80131524: Failed to create the bootstrapper application

Basically, my installer has a custom UI built using WPF (.Net Framework), an msi built using Wix Toolset v4 and using Bundle to create the exe.

Log says:

Error 0x80131508: Failed to create the bootstrapper application. Error 0x80131508: Failed to create the managed bootstrapper application. Error 0x80131508: Failed to create BA. Error 0x80131508: Failed to load BA. Error 0x80131508: Failed while running

Here is the project file of the UI:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>    
    <RuntimeIdentifier>win-x86</RuntimeIdentifier>
  </PropertyGroup>
  
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <PlatformTarget>x86</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\x86\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.DirectoryServices.AccountManagement" />
    <Reference Include="System.ServiceProcess" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xaml" />
      
  
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
    <PackageReference Include="Newtonsoft.Json">
      <Version>13.0.3</Version>
    </PackageReference>
    <PackageReference Include="WixToolset.Mba.Core" Version="4.0.*" PrivateAssets="All" GeneratePathProperty="true" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="WixToolset.Mba.Host.config" CopyToOutputDirectory="PreserveNewest" />
    <Content Include="$(PkgWixToolset_Mba_Core)\runtimes\win-x86\native\mbanative.dll">
      <Visible>false</Visible>
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
      <IsAssembly>false</IsAssembly>
    </Content>
  </ItemGroup>
  <ItemGroup>
    
    <Page Include="AdditionalStyles.xaml">
      <SubType>Designer</SubType>
      <Generator>MSBuild:Compile</Generator>
    </Page>
    <Page Include="MainWindow.xaml">
      <Generator>MSBuild:Compile</Generator>
      <SubType>Designer</SubType>
    </Page>
   
  </ItemGroup>
 
  
 
</Project>

CustomUI.cs

using System.Windows.Threading;
using WixToolset.Mba.Core;

namespace MyOwnApp
{
   public class CustomUI : BootstrapperApplication
    {
        public CustomUI(IEngine engine) : base(engine)
        {
        }

        public IEngine Engine => this.engine;
        public static Dispatcher BootstrapperDispatcher { get; private set; }

        protected override void Run()
        {
            this.Engine.Log(LogLevel.Verbose, "Launching Custom UI");
            BootstrapperDispatcher = Dispatcher.CurrentDispatcher;

            MainWindow view = new MainWindow(this);
            view.Bootstrapper.Engine.Detect();        
            view.DataContext = view;
            view.Closed += (sender, e) => BootstrapperDispatcher.InvokeShutdown();
            view.Show();

            Dispatcher.Run();
            this.Engine.Quit(0);
        }

        protected override void OnStartup(StartupEventArgs args)
        {
            base.OnStartup(args);

            this.engine.Log(LogLevel.Standard, nameof(CustomUI));
        }

        protected override void OnShutdown(ShutdownEventArgs args)
        {
            base.OnShutdown(args);

            var message = "Shutdown," + args.Action.ToString() + "," + args.HResult.ToString();
            this.engine.Log(LogLevel.Standard, message);
        }
    }
}

CustomUIFactory:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyOwnApp
{
    using WixToolset.Mba.Core;
    public class CustomUIFactory : BaseBootstrapperApplicationFactory
    {
        private static int loadCount = 0;

        protected override IBootstrapperApplication Create(IEngine engine, IBootstrapperCommand bootstrapperCommand)
        {
            if (loadCount > 0)
            {
                engine.Log(LogLevel.Standard, $"Reloaded {loadCount} time(s)");
            }
            ++loadCount;
            return new CustomUI(engine);
        }
    }
}

WixToolset.Mba.Host.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="wix.bootstrapper" type="WixToolset.Mba.Host.BootstrapperSectionGroup, WixToolset.Mba.Host">
      <section name="host" type="WixToolset.Mba.Host.HostSection, WixToolset.Mba.Host" />
    </sectionGroup>
  </configSections>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
  </startup>
  <wix.bootstrapper>
    <host assemblyName="MyOwnApp" />
  </wix.bootstrapper>
</configuration>

Tried almost all of the examples found on the internet to no avail. :(

Upvotes: 1

Views: 823

Answers (1)

mcross5129
mcross5129

Reputation: 24

After many hours of struggling myself, I finally found a solution that worked for me.

When using .NET Framework, your AssemblyInfo.cs file needs a reference to the BootstrapperApplicationFactory implementation (in your case CustomUIFactory) like this:

using Bootstrapper;
using System.Windows;
using WixToolset.Mba.Core;

[assembly: ThemeInfo(
    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
                                     //(used if a resource is not found in the page,
                                     // or application resource dictionaries)
    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
                                              //(used if a resource is not found in the page,
                                              // app, or any theme specific resource dictionaries)
)]

[assembly: BootstrapperApplicationFactory(typeof(CustomUIFactory))]

This reference used to be to the BootstrapperApplication class in WiX v3, but that is no longer the case in v4 since it is now abstract.

Alternatively, the

[assembly: BootstrapperApplicationFactory(typeof(CustomUIFactory))]

can also be included at the top of your factory class above the namespace.

Upvotes: 1

Related Questions