WiX v4 bootstrapper process remains alive after installation ends

I have a WiX v4 managed BA that has many redistributables as prerequisites. The installation completes and everything is installed successfully, but frequently the 3 bootstrapper processes never terminate even after the UI is closed and Engine.Quit(0) is called. The redistributable installers exit successfully and there are no issues in their logs, so I assume the issue is coming from my BA.

In my bundle I have the redistributables included as follows:

<ExePackage 
    bal:PrereqPackage="yes" 
    Id="NetFramework48" 
    PerMachine="yes" 
    DetectCondition="NETFRAMEWORK45 >= 528040" 
    Vital="yes" 
    Permanent="yes" 
    Protocol="netfx4" 
    LogPathVariable="NetFxInstallLog" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesndp48-x86-x64-allos-enu.exe" 
    Name="redistndp48-x86-x64-allos-enu.exe" 
    InstallArguments="/q /norestart /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" 
    RepairArguments="/q /norestart /repair /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" 
    UninstallArguments="/uninstall /q /norestart /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" />

<ExePackage 
    Id="DotNET6DesktopRuntimeX86" 
    PerMachine="yes" 
    DetectCondition="DotNET6DesktopRuntimex86Installed" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6windowsdesktop-runtime-6.0.11-win-x86.exe" 
    Name="redistwindowsdesktop-runtime-6.0.11-win-x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart">
    <ExitCode Behavior="success" Value="0" />
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638" />
</ExePackage>

<ExePackage 
    Id="DotNET6DesktopRuntimeX64" 
    PerMachine="yes" 
    DetectCondition="DotNET6DesktopRuntimex64Installed" 
    Vital="yes" Permanent="yes" Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6windowsdesktop-runtime-6.0.11-win-x64.exe" 
    Name="redistwindowsdesktop-runtime-6.0.11-win-x64.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart">
    <ExitCode Behavior="success" Value="0" />
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638" />
</ExePackage>

<ExePackage 
    Id="DotNET6AspCoreRuntimeX86" 
    PerMachine="yes" 
    DetectCondition="DotNET6ASPCoreRuntimex86Installed" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6aspnetcore-runtime-6.0.11-win-x86.exe" 
    Name="redistaspnetcore-runtime-6.0.11-win-x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart" />

<ExePackage
    Id="DotNET8DesktopRuntimeX86"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8DesktopRuntimex86Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8windowsdesktop-runtime-8.0.7-win-x86.exe"
    Name="redistwindowsdesktop-runtime-8.0.7-win-x86.exe">
    <ExitCode Behavior="success" Value="0"/>
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638"/>
</ExePackage>

<ExePackage
    Id="DotNET8DesktopRuntimeX64"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8DesktopRuntimex64Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8windowsdesktop-runtime-8.0.7-win-x64.exe"
    Name="redistwindowsdesktop-runtime-8.0.7-win-x64.exe">
    <ExitCode Behavior="success" Value="0"/>
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638"/>
</ExePackage>

<ExePackage
    Id="DotNET8AspCoreRuntimeX86"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8ASPCoreRuntimex86Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8aspnetcore-runtime-8.0.7-win-x86.exe"
    Name="redistaspnetcore-runtime-8.0.7-win-x86.exe"/>

<ExePackage 
    Id="VisualCPlusPlus14Runtime" 
    PerMachine="yes" 
    DetectCondition="VC14RuntimeInstalled > v0.0.0.0" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesVisual C++VC++2015-2022_x86.exe" 
    Name="redistVC++2015-2022_x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart" />

<ExePackage 
    Id="DirectX9C" 
    PerMachine="yes" 
    DetectCondition="DirectX9cInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDirectx90cDXSETUP.exe" 
    Name="redistDirectx90cDXSETUP.exe" 
    InstallArguments="/silent">
    <PayloadGroupRef Id="DirectX9cPayloadGroup" />
</ExePackage>

<ExePackage 
    Id="MicrosoftAccess2010DatabaseEngine" 
    PerMachine="yes" 
    DetectCondition="MSAccess2010DbEngineInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesAccessDatabaseEngine.exe" 
    Name="redistAccessDatabaseEngine.exe" 
    InstallArguments="/quiet /norestart" />

<MsiPackage 
    Id="Powershell" 
    InstallCondition="NOT PowershellInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesPowershellPowerShell-7.3.11-win-x86.msi" 
    Name="redistPowerShell-7.3.11-win-x86.msi" />

And my BA class is:

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

namespace Bootstrapper
{
    /// <summary>
    /// The custom bootstrapper application.
    /// </summary>
    public class CustomBA : BootstrapperApplication, ICustomBA
    {
#nullable enable

        public CustomBA(IEngine engine, IBootstrapperCommand command) : base(engine)
        {
            Engine = engine;
            Command = command;
        }

        /// <inheritdoc/>
        public IEngine Engine { get; set; }

        /// <inheritdoc/>
        public IBootstrapperCommand Command { get; set; }

        /// <summary>
        /// The global dispatcher.
        /// </summary>
        static public Dispatcher? BootstrapperDispatcher { get; private set; }

        /// <summary>
        /// The entry point for the custom UI.
        /// </summary>
        protected override void Run()
        {

            this.Engine.Log(LogLevel.Standard, "Launching custom bootstrapper UX");
            BootstrapperDispatcher = Dispatcher.CurrentDispatcher;

            MainWindowViewModel viewModel = new MainWindowViewModel(this);

            MainWindow view = new MainWindow();
            view.DataContext = viewModel;
            view.Closed += (sender, e) => BootstrapperDispatcher.InvokeShutdown();

            if (!viewModel.silent)
            {
                view.Show();
            }

            Dispatcher.Run();

            this.Engine.Quit(0);

        }
    }
}

From the logs it almost looks like the BA is hanging before it is able to execute the cleanup after Engine.Quit.

The bundle log ends with:

[098C:18D8][2024-07-31T13:40:42]i399: Apply complete, result: 0x0, restart: None, ba requested restart:  No
[098C:0B88][2024-07-31T13:45:23]i000: Dispatch complete, quitting engine. 
[098C:18D8][2024-07-31T13:45:23]i500: Shutting down, exit code: 0x0

Whereas the expected lines afterwords about

Cleanup begin.
Cleanup not required due to running Apply.
Cleanup complete, result: 0x0
All the variable ending values blah blah
Exit code: 0x0, restarting: No

Never appear.

Often (not always) if I install the NET Desktop Runtime redistributable myself BEFORE running the BA, the process terminates as expected and the cleanup is executed.

This happens on a fresh, completely new install.
There are no pending reboot or file moves I can see.
The BA is not encountering any obvious exceptions or giving any event viewer information.

Killing the process myself after Engine.Quit(0) using something like Process.GetCurrentProcess().Kill(); works, but is skipping any potential cleanup, shutdown events, and just feels gross in general.

This was not a problem with the same logic in v3, so either something with the upgrade to v4 is incorrect or v4 itself had a behavior change (some new asynchronous stuff?) regarding this that I cannot track down.

I can provide any additional log or code information upon request.

Any help or even left-field suggestions would be appreciated 🙂

0

The issue was being caused by passing a dummy handle to Engine.Apply.

 private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
 {
     Bootstrapper.Engine.Log(LogLevel.Standard, $"Plan complete with status: {e.Status}");

     if (e.Status >= 0)
     {
         // Pass in a dummy handle since as of WiX v4, Apply no longer supports a handle of zero.
         // This handle is used for parenting Burn child UIs to the BA window, not needed for us.
         Bootstrapper.Engine.Apply(new System.Windows.Forms.Form().Handle);
     }
 }

Without a real handle, the engine (sometimes?????) seems to be unable to clean up after itself when quitting, even if the install completes fine.

Getting the actual handle from the View using new WindowInteropHelper(this).EnsureHandle(); and passing that to Apply instead like so:

private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
{
    Bootstrapper.Engine.Log(LogLevel.Standard, $"Plan complete with status: {e.Status}");

    if (e.Status >= 0)
    {
        // Use real window handle from the view.
        Bootstrapper.Engine.Log(LogLevel.Standard, $"Applying with window handle: {Bootstrapper.Handle}");
        Bootstrapper.Engine.Apply(Bootstrapper.Handle);
    }
}

Fixed the issue for me.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

WiX v4 bootstrapper process remains alive after installation ends

I have a WiX v4 managed BA that has many redistributables as prerequisites. The installation completes and everything is installed successfully, but frequently the 3 bootstrapper processes never terminate even after the UI is closed and Engine.Quit(0) is called. The redistributable installers exit successfully and there are no issues in their logs, so I assume the issue is coming from my BA.

In my bundle I have the redistributables included as follows:

<ExePackage 
    bal:PrereqPackage="yes" 
    Id="NetFramework48" 
    PerMachine="yes" 
    DetectCondition="NETFRAMEWORK45 >= 528040" 
    Vital="yes" 
    Permanent="yes" 
    Protocol="netfx4" 
    LogPathVariable="NetFxInstallLog" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesndp48-x86-x64-allos-enu.exe" 
    Name="redistndp48-x86-x64-allos-enu.exe" 
    InstallArguments="/q /norestart /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" 
    RepairArguments="/q /norestart /repair /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" 
    UninstallArguments="/uninstall /q /norestart /ChainingPackage "[WixBundleName]" /log "[NetFxInstallLog].html"" />

<ExePackage 
    Id="DotNET6DesktopRuntimeX86" 
    PerMachine="yes" 
    DetectCondition="DotNET6DesktopRuntimex86Installed" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6windowsdesktop-runtime-6.0.11-win-x86.exe" 
    Name="redistwindowsdesktop-runtime-6.0.11-win-x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart">
    <ExitCode Behavior="success" Value="0" />
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638" />
</ExePackage>

<ExePackage 
    Id="DotNET6DesktopRuntimeX64" 
    PerMachine="yes" 
    DetectCondition="DotNET6DesktopRuntimex64Installed" 
    Vital="yes" Permanent="yes" Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6windowsdesktop-runtime-6.0.11-win-x64.exe" 
    Name="redistwindowsdesktop-runtime-6.0.11-win-x64.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart">
    <ExitCode Behavior="success" Value="0" />
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638" />
</ExePackage>

<ExePackage 
    Id="DotNET6AspCoreRuntimeX86" 
    PerMachine="yes" 
    DetectCondition="DotNET6ASPCoreRuntimex86Installed" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET6aspnetcore-runtime-6.0.11-win-x86.exe" 
    Name="redistaspnetcore-runtime-6.0.11-win-x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart" />

<ExePackage
    Id="DotNET8DesktopRuntimeX86"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8DesktopRuntimex86Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8windowsdesktop-runtime-8.0.7-win-x86.exe"
    Name="redistwindowsdesktop-runtime-8.0.7-win-x86.exe">
    <ExitCode Behavior="success" Value="0"/>
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638"/>
</ExePackage>

<ExePackage
    Id="DotNET8DesktopRuntimeX64"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8DesktopRuntimex64Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8windowsdesktop-runtime-8.0.7-win-x64.exe"
    Name="redistwindowsdesktop-runtime-8.0.7-win-x64.exe">
    <ExitCode Behavior="success" Value="0"/>
    <!-- Error Code 0x666 or 1638 means a newer version was detected -->
    <ExitCode Behavior="success" Value="1638"/>
</ExePackage>

<ExePackage
    Id="DotNET8AspCoreRuntimeX86"
    InstallArguments="/install /quiet /norestart"
    RepairArguments="/repair /quiet /norestart"
    UninstallArguments="/uninstall /quiet /norestart"
    PerMachine="yes"
    DetectCondition="DotNET8ASPCoreRuntimex86Installed"
    Vital="yes"
    Permanent="yes"
    Compressed="no"
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDotNET8aspnetcore-runtime-8.0.7-win-x86.exe"
    Name="redistaspnetcore-runtime-8.0.7-win-x86.exe"/>

<ExePackage 
    Id="VisualCPlusPlus14Runtime" 
    PerMachine="yes" 
    DetectCondition="VC14RuntimeInstalled > v0.0.0.0" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesVisual C++VC++2015-2022_x86.exe" 
    Name="redistVC++2015-2022_x86.exe" 
    InstallArguments="/install /quiet /norestart" 
    RepairArguments="/repair /quiet /norestart" 
    UninstallArguments="/uninstall /quiet /norestart" />

<ExePackage 
    Id="DirectX9C" 
    PerMachine="yes" 
    DetectCondition="DirectX9cInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesDirectx90cDXSETUP.exe" 
    Name="redistDirectx90cDXSETUP.exe" 
    InstallArguments="/silent">
    <PayloadGroupRef Id="DirectX9cPayloadGroup" />
</ExePackage>

<ExePackage 
    Id="MicrosoftAccess2010DatabaseEngine" 
    PerMachine="yes" 
    DetectCondition="MSAccess2010DbEngineInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesAccessDatabaseEngine.exe" 
    Name="redistAccessDatabaseEngine.exe" 
    InstallArguments="/quiet /norestart" />

<MsiPackage 
    Id="Powershell" 
    InstallCondition="NOT PowershellInstalled" 
    Vital="yes" 
    Permanent="yes" 
    Compressed="no" 
    SourceFile="$(var.SolutionDir)ResourcesRedistributablesPowershellPowerShell-7.3.11-win-x86.msi" 
    Name="redistPowerShell-7.3.11-win-x86.msi" />

And my BA class is:

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

namespace Bootstrapper
{
    /// <summary>
    /// The custom bootstrapper application.
    /// </summary>
    public class CustomBA : BootstrapperApplication, ICustomBA
    {
#nullable enable

        public CustomBA(IEngine engine, IBootstrapperCommand command) : base(engine)
        {
            Engine = engine;
            Command = command;
        }

        /// <inheritdoc/>
        public IEngine Engine { get; set; }

        /// <inheritdoc/>
        public IBootstrapperCommand Command { get; set; }

        /// <summary>
        /// The global dispatcher.
        /// </summary>
        static public Dispatcher? BootstrapperDispatcher { get; private set; }

        /// <summary>
        /// The entry point for the custom UI.
        /// </summary>
        protected override void Run()
        {

            this.Engine.Log(LogLevel.Standard, "Launching custom bootstrapper UX");
            BootstrapperDispatcher = Dispatcher.CurrentDispatcher;

            MainWindowViewModel viewModel = new MainWindowViewModel(this);

            MainWindow view = new MainWindow();
            view.DataContext = viewModel;
            view.Closed += (sender, e) => BootstrapperDispatcher.InvokeShutdown();

            if (!viewModel.silent)
            {
                view.Show();
            }

            Dispatcher.Run();

            this.Engine.Quit(0);

        }
    }
}

From the logs it almost looks like the BA is hanging before it is able to execute the cleanup after Engine.Quit.

The bundle log ends with:

[098C:18D8][2024-07-31T13:40:42]i399: Apply complete, result: 0x0, restart: None, ba requested restart:  No
[098C:0B88][2024-07-31T13:45:23]i000: Dispatch complete, quitting engine. 
[098C:18D8][2024-07-31T13:45:23]i500: Shutting down, exit code: 0x0

Whereas the expected lines afterwords about

Cleanup begin.
Cleanup not required due to running Apply.
Cleanup complete, result: 0x0
All the variable ending values blah blah
Exit code: 0x0, restarting: No

Never appear.

Often (not always) if I install the NET Desktop Runtime redistributable myself BEFORE running the BA, the process terminates as expected and the cleanup is executed.

This happens on a fresh, completely new install.
There are no pending reboot or file moves I can see.
The BA is not encountering any obvious exceptions or giving any event viewer information.

Killing the process myself after Engine.Quit(0) using something like Process.GetCurrentProcess().Kill(); works, but is skipping any potential cleanup, shutdown events, and just feels gross in general.

This was not a problem with the same logic in v3, so either something with the upgrade to v4 is incorrect or v4 itself had a behavior change (some new asynchronous stuff?) regarding this that I cannot track down.

I can provide any additional log or code information upon request.

Any help or even left-field suggestions would be appreciated 🙂

0

The issue was being caused by passing a dummy handle to Engine.Apply.

 private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
 {
     Bootstrapper.Engine.Log(LogLevel.Standard, $"Plan complete with status: {e.Status}");

     if (e.Status >= 0)
     {
         // Pass in a dummy handle since as of WiX v4, Apply no longer supports a handle of zero.
         // This handle is used for parenting Burn child UIs to the BA window, not needed for us.
         Bootstrapper.Engine.Apply(new System.Windows.Forms.Form().Handle);
     }
 }

Without a real handle, the engine (sometimes?????) seems to be unable to clean up after itself when quitting, even if the install completes fine.

Getting the actual handle from the View using new WindowInteropHelper(this).EnsureHandle(); and passing that to Apply instead like so:

private void OnPlanComplete(object sender, PlanCompleteEventArgs e)
{
    Bootstrapper.Engine.Log(LogLevel.Standard, $"Plan complete with status: {e.Status}");

    if (e.Status >= 0)
    {
        // Use real window handle from the view.
        Bootstrapper.Engine.Log(LogLevel.Standard, $"Applying with window handle: {Bootstrapper.Handle}");
        Bootstrapper.Engine.Apply(Bootstrapper.Handle);
    }
}

Fixed the issue for me.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật