From ae1751902076edfd8978b7fb42f24d3ac3f7ad55 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Wed, 29 Apr 2020 19:36:24 +1000 Subject: Add WPF .NET Core test. --- .../WixToolsetTest.ManagedHost/DncHostFixture.cs | 34 +++++++++ .../WPFCoreMBA/FrameworkDependentBundle.wxs | 17 +++++ .../WixToolsetTest.ManagedHost.csproj | 17 ++++- .../examples/TestEngine/Example.TestEngine.vcxproj | 2 + src/test/examples/TestEngine/ExampleTestEngine.cpp | 21 +++++- src/test/examples/TestEngine/ReloadEngine.cpp | 12 ++++ src/test/examples/TestEngine/ShutdownEngine.cpp | 6 ++ src/test/examples/TestEngine/TestEngine.cpp | 83 ++++++++++++++++++++-- src/test/examples/TestEngine/TestEngine.h | 35 ++++++++- src/test/examples/TestEngine/WaitForQuitEngine.cpp | 35 +++++++++ src/test/examples/TestEngine/WaitForQuitEngine.h | 8 +++ src/test/examples/TestEngine/precomp.h | 1 + src/test/examples/WPFCoreMBA/AssemblyInfo.cs | 12 ++++ .../examples/WPFCoreMBA/Example.WPFCoreMBA.csproj | 16 +++++ src/test/examples/WPFCoreMBA/MainWindow.xaml | 16 +++++ src/test/examples/WPFCoreMBA/MainWindow.xaml.cs | 17 +++++ src/test/examples/WPFCoreMBA/WPFCoreBA.cs | 42 +++++++++++ src/test/examples/WPFCoreMBA/WPFCoreBAFactory.cs | 22 ++++++ 18 files changed, 384 insertions(+), 12 deletions(-) create mode 100644 src/test/WixToolsetTest.ManagedHost/TestData/WPFCoreMBA/FrameworkDependentBundle.wxs create mode 100644 src/test/examples/TestEngine/WaitForQuitEngine.cpp create mode 100644 src/test/examples/TestEngine/WaitForQuitEngine.h create mode 100644 src/test/examples/WPFCoreMBA/AssemblyInfo.cs create mode 100644 src/test/examples/WPFCoreMBA/Example.WPFCoreMBA.csproj create mode 100644 src/test/examples/WPFCoreMBA/MainWindow.xaml create mode 100644 src/test/examples/WPFCoreMBA/MainWindow.xaml.cs create mode 100644 src/test/examples/WPFCoreMBA/WPFCoreBA.cs create mode 100644 src/test/examples/WPFCoreMBA/WPFCoreBAFactory.cs (limited to 'src') diff --git a/src/test/WixToolsetTest.ManagedHost/DncHostFixture.cs b/src/test/WixToolsetTest.ManagedHost/DncHostFixture.cs index 7f40ee26..f33709ab 100644 --- a/src/test/WixToolsetTest.ManagedHost/DncHostFixture.cs +++ b/src/test/WixToolsetTest.ManagedHost/DncHostFixture.cs @@ -335,5 +335,39 @@ namespace WixToolsetTest.ManagedHost Assert.Equal("Shutdown,Restart,0", logMessages[8]); } } + + [Fact] + public void CanLoadFDDWPFCoreMBA() + { + using (var fs = new DisposableFileSystem()) + { + var baseFolder = fs.GetFolder(); + var binFolder = Path.Combine(baseFolder, "bin"); + var bundleFile = Path.Combine(binFolder, "FDDWPFCoreMBA.exe"); + var baSourceFolder = TestData.Get(@"..\examples"); + var bundleSourceFolder = TestData.Get(@"TestData\WPFCoreMBA"); + var intermediateFolder = Path.Combine(baseFolder, "obj"); + + var compileResult = WixRunner.Execute(new[] + { + "build", + Path.Combine(bundleSourceFolder, "FrameworkDependentBundle.wxs"), + "-ext", TestData.Get(@"WixToolset.Bal.wixext.dll"), + "-intermediateFolder", intermediateFolder, + "-bindpath", baSourceFolder, + "-burnStub", TestEngine.BurnStubFile, + "-o", bundleFile, + }); + compileResult.AssertSuccess(); + var testEngine = new TestEngine(); + + var result = testEngine.RunShutdownEngine(bundleFile, baseFolder); + var logMessages = result.Output; + Assert.Equal("Loading .NET Core FDD bootstrapper application.", logMessages[0]); + Assert.Equal("Creating BA thread to run asynchronously.", logMessages[1]); + Assert.Equal("WPFCoreBA", logMessages[2]); + Assert.Equal("Shutdown,ReloadBootstrapper,0", logMessages[3]); + } + } } } diff --git a/src/test/WixToolsetTest.ManagedHost/TestData/WPFCoreMBA/FrameworkDependentBundle.wxs b/src/test/WixToolsetTest.ManagedHost/TestData/WPFCoreMBA/FrameworkDependentBundle.wxs new file mode 100644 index 00000000..ecc5e8c1 --- /dev/null +++ b/src/test/WixToolsetTest.ManagedHost/TestData/WPFCoreMBA/FrameworkDependentBundle.wxs @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + diff --git a/src/test/WixToolsetTest.ManagedHost/WixToolsetTest.ManagedHost.csproj b/src/test/WixToolsetTest.ManagedHost/WixToolsetTest.ManagedHost.csproj index 958c63fc..ff472322 100644 --- a/src/test/WixToolsetTest.ManagedHost/WixToolsetTest.ManagedHost.csproj +++ b/src/test/WixToolsetTest.ManagedHost/WixToolsetTest.ManagedHost.csproj @@ -14,6 +14,7 @@ ..\examples\EarliestCoreMBA\Example.EarliestCoreMBA.csproj ..\examples\LatestCoreMBA\Example.LatestCoreMBA.csproj + ..\examples\WPFCoreMBA\Example.WPFCoreMBA.csproj $(OutputPath)examples\publish\ @@ -30,6 +31,7 @@ + @@ -43,11 +45,17 @@ $(MBAPublishPath)Example.LatestCoreMBA + + $(MBAPublishPath)Example.WPFCoreMBA + true + true + + @@ -69,8 +77,11 @@ - - - + + + diff --git a/src/test/examples/TestEngine/Example.TestEngine.vcxproj b/src/test/examples/TestEngine/Example.TestEngine.vcxproj index be52105b..b9425295 100644 --- a/src/test/examples/TestEngine/Example.TestEngine.vcxproj +++ b/src/test/examples/TestEngine/Example.TestEngine.vcxproj @@ -50,12 +50,14 @@ + + diff --git a/src/test/examples/TestEngine/ExampleTestEngine.cpp b/src/test/examples/TestEngine/ExampleTestEngine.cpp index a378c9a3..fc1938fe 100644 --- a/src/test/examples/TestEngine/ExampleTestEngine.cpp +++ b/src/test/examples/TestEngine/ExampleTestEngine.cpp @@ -4,9 +4,15 @@ int __cdecl wmain(int argc, LPWSTR argv[]) { - HRESULT hr = E_INVALIDARG; + HRESULT hr = S_OK; + BOOL fComInitialized = FALSE; BOOL fShowUsage = FALSE; + // initialize COM + hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); + ExitOnFailure(hr, "Failed to initialize COM."); + fComInitialized = TRUE; + ConsoleInitialize(); if (argc != 4) @@ -21,6 +27,10 @@ int __cdecl wmain(int argc, LPWSTR argv[]) { hr = RunShutdownEngine(argv[2], argv[3]); } + else if (CSTR_EQUAL == ::CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, argv[1], -1, L"waitforquit", -1)) + { + hr = RunWaitForQuitEngine(argv[2], argv[3]); + } else { fShowUsage = TRUE; @@ -28,9 +38,16 @@ int __cdecl wmain(int argc, LPWSTR argv[]) if (fShowUsage) { - ConsoleWriteError(hr, CONSOLE_COLOR_RED, "Usage: {reload|shutdown} Example.TestEngine.exe Bundle.exe BA.dll"); + ConsoleWriteError(hr = E_INVALIDARG, CONSOLE_COLOR_RED, "Usage: Example.TestEngine.exe {reload|shutdown|waitforquit} Bundle.exe BA.dll"); } ConsoleUninitialize(); + +LExit: + if (fComInitialized) + { + ::CoUninitialize(); + } + return hr; } diff --git a/src/test/examples/TestEngine/ReloadEngine.cpp b/src/test/examples/TestEngine/ReloadEngine.cpp index 83541672..46fd9afa 100644 --- a/src/test/examples/TestEngine/ReloadEngine.cpp +++ b/src/test/examples/TestEngine/ReloadEngine.cpp @@ -22,6 +22,12 @@ HRESULT RunReloadEngine( hr = pTestEngine->SendStartupEvent(); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnStartup."); + hr = pTestEngine->SimulateQuit(0); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to simulate quit."); + + hr = pTestEngine->RunApplication(); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to run engine."); + hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown."); @@ -33,6 +39,12 @@ HRESULT RunReloadEngine( hr = pTestEngine->SendStartupEvent(); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnStartup."); + hr = pTestEngine->SimulateQuit(0); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to simulate quit."); + + hr = pTestEngine->RunApplication(); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to run engine."); + hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RESTART); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown."); diff --git a/src/test/examples/TestEngine/ShutdownEngine.cpp b/src/test/examples/TestEngine/ShutdownEngine.cpp index 0dfbb429..3b876e4e 100644 --- a/src/test/examples/TestEngine/ShutdownEngine.cpp +++ b/src/test/examples/TestEngine/ShutdownEngine.cpp @@ -22,6 +22,12 @@ HRESULT RunShutdownEngine( hr = pTestEngine->SendStartupEvent(); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnStartup."); + hr = pTestEngine->SimulateQuit(0); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to simulate quit."); + + hr = pTestEngine->RunApplication(); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to run engine."); + hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown."); diff --git a/src/test/examples/TestEngine/TestEngine.cpp b/src/test/examples/TestEngine/TestEngine.cpp index f0811e0a..7b7dafce 100644 --- a/src/test/examples/TestEngine/TestEngine.cpp +++ b/src/test/examples/TestEngine/TestEngine.cpp @@ -7,12 +7,15 @@ HRESULT TestEngine::Initialize( ) { HRESULT hr = S_OK; + MSG msg = { }; LogInitialize(::GetModuleHandleW(NULL)); hr = LogOpen(NULL, PathFile(wzBundleFilePath), NULL, L"txt", FALSE, FALSE, NULL); ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to open log."); + ::PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + LExit: return hr; } @@ -73,6 +76,29 @@ HRESULT TestEngine::Log( return ConsoleWriteLine(CONSOLE_COLOR_NORMAL, "%ls", wzMessage); } +HRESULT TestEngine::RunApplication() +{ + HRESULT hr = S_OK; + MSG msg = { }; + BOOL fRet = FALSE; + + // Enter the message pump. + while (0 != (fRet = ::GetMessageW(&msg, NULL, 0, 0))) + { + if (-1 == fRet) + { + ConsoleExitOnFailure(hr = E_UNEXPECTED, CONSOLE_COLOR_RED, "Unexpected return value from message pump."); + } + else + { + ProcessBAMessage(&msg); + } + } + +LExit: + return hr; +} + HRESULT TestEngine::SendShutdownEvent( __in BOOTSTRAPPER_SHUTDOWN_ACTION defaultAction ) @@ -98,6 +124,21 @@ HRESULT TestEngine::SendStartupEvent() return hr; } +HRESULT TestEngine::SimulateQuit( + __in DWORD dwExitCode + ) +{ + BAENGINE_QUIT_ARGS args = { }; + BAENGINE_QUIT_RESULTS results = { }; + + args.cbSize = sizeof(BAENGINE_QUIT_ARGS); + args.dwExitCode = dwExitCode; + + results.cbSize = sizeof(BAENGINE_QUIT_RESULTS); + + return BAEngineQuit(&args, &results); +} + void TestEngine::UnloadBA() { PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = NULL; @@ -124,12 +165,27 @@ void TestEngine::UnloadBA() } HRESULT TestEngine::BAEngineLog( - __in TestEngine* pContext, __in BAENGINE_LOG_ARGS* pArgs, __in BAENGINE_LOG_RESULTS* /*pResults*/ ) { - return pContext->Log(pArgs->wzMessage); + return Log(pArgs->wzMessage); +} + +HRESULT TestEngine::BAEngineQuit( + __in BAENGINE_QUIT_ARGS* pArgs, + __in BAENGINE_QUIT_RESULTS* /*pResults*/ + ) +{ + HRESULT hr = S_OK; + + if (!::PostThreadMessageW(m_dwThreadId, WM_TESTENG_QUIT, static_cast(pArgs->dwExitCode), 0)) + { + ExitWithLastError(hr, "Failed to post shutdown message."); + } + +LExit: + return hr; } HRESULT WINAPI TestEngine::EngineProc( @@ -150,8 +206,10 @@ HRESULT WINAPI TestEngine::EngineProc( switch (message) { case BOOTSTRAPPER_ENGINE_MESSAGE_LOG: - hr = BAEngineLog(pContext, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + hr = pContext->BAEngineLog(reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); break; + case BOOTSTRAPPER_ENGINE_MESSAGE_QUIT: + hr = pContext->BAEngineQuit(reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); default: hr = E_NOTIMPL; break; @@ -161,13 +219,30 @@ LExit: return hr; } +HRESULT TestEngine::ProcessBAMessage( + __in const MSG* pmsg + ) +{ + HRESULT hr = S_OK; + + switch (pmsg->message) + { + case WM_TESTENG_QUIT: + ::PostQuitMessage(static_cast(pmsg->wParam)); // go bye-bye. + break; + } + + return hr; +} + TestEngine::TestEngine() { m_hBAModule = NULL; m_pCreateResults = NULL; + m_dwThreadId = ::GetCurrentThreadId(); } TestEngine::~TestEngine() { ReleaseMem(m_pCreateResults); -} \ No newline at end of file +} diff --git a/src/test/examples/TestEngine/TestEngine.h b/src/test/examples/TestEngine/TestEngine.h index cf1c8aac..14b69999 100644 --- a/src/test/examples/TestEngine/TestEngine.h +++ b/src/test/examples/TestEngine/TestEngine.h @@ -2,6 +2,20 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. +enum WM_TESTENG +{ + WM_TESTENG_FIRST = WM_APP + 0xFFF, // this enum value must always be first. + + WM_TESTENG_DETECT, + WM_TESTENG_PLAN, + WM_TESTENG_ELEVATE, + WM_TESTENG_APPLY, + WM_TESTENG_LAUNCH_APPROVED_EXE, + WM_TESTENG_QUIT, + + WM_TESTENG_LAST, // this enum value must always be last. +}; + class TestEngine { public: @@ -17,19 +31,29 @@ public: __in LPCWSTR wzMessage ); + HRESULT RunApplication(); + HRESULT SendShutdownEvent( __in BOOTSTRAPPER_SHUTDOWN_ACTION defaultAction ); HRESULT SendStartupEvent(); + HRESULT SimulateQuit( + __in DWORD dwExitCode + ); + void UnloadBA(); private: - static HRESULT BAEngineLog( - __in TestEngine* pContext, + HRESULT BAEngineLog( __in BAENGINE_LOG_ARGS* pArgs, - __in BAENGINE_LOG_RESULTS* /*pResults*/ + __in BAENGINE_LOG_RESULTS* pResults + ); + + HRESULT BAEngineQuit( + __in BAENGINE_QUIT_ARGS* pArgs, + __in BAENGINE_QUIT_RESULTS* pResults ); static HRESULT WINAPI EngineProc( @@ -39,6 +63,10 @@ private: __in_opt LPVOID pvContext ); + HRESULT ProcessBAMessage( + __in const MSG* pmsg + ); + public: TestEngine(); @@ -47,4 +75,5 @@ public: private: HMODULE m_hBAModule; BOOTSTRAPPER_CREATE_RESULTS* m_pCreateResults; + DWORD m_dwThreadId; }; \ No newline at end of file diff --git a/src/test/examples/TestEngine/WaitForQuitEngine.cpp b/src/test/examples/TestEngine/WaitForQuitEngine.cpp new file mode 100644 index 00000000..2f80ba75 --- /dev/null +++ b/src/test/examples/TestEngine/WaitForQuitEngine.cpp @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +HRESULT RunWaitForQuitEngine( + __in LPCWSTR wzBundleFilePath, + __in LPCWSTR wzBAFilePath + ) +{ + HRESULT hr = S_OK; + TestEngine* pTestEngine = NULL; + + pTestEngine = new TestEngine(); + ConsoleExitOnNull(pTestEngine, hr, E_OUTOFMEMORY, CONSOLE_COLOR_RED, "Failed to create new test engine."); + + hr = pTestEngine->Initialize(wzBundleFilePath); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to initialize engine."); + + hr = pTestEngine->LoadBA(wzBAFilePath); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to load BA."); + + hr = pTestEngine->SendStartupEvent(); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnStartup."); + + hr = pTestEngine->RunApplication(); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "Failed to run engine."); + + hr = pTestEngine->SendShutdownEvent(BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER); + ConsoleExitOnFailure(hr, CONSOLE_COLOR_RED, "BA returned failure for OnShutdown."); + + pTestEngine->UnloadBA(); + +LExit: + return hr; +} diff --git a/src/test/examples/TestEngine/WaitForQuitEngine.h b/src/test/examples/TestEngine/WaitForQuitEngine.h new file mode 100644 index 00000000..99e3f63c --- /dev/null +++ b/src/test/examples/TestEngine/WaitForQuitEngine.h @@ -0,0 +1,8 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +HRESULT RunWaitForQuitEngine( + __in LPCWSTR wzBundleFilePath, + __in LPCWSTR wzBAFilePath + ); diff --git a/src/test/examples/TestEngine/precomp.h b/src/test/examples/TestEngine/precomp.h index 3fbc7e90..f943f420 100644 --- a/src/test/examples/TestEngine/precomp.h +++ b/src/test/examples/TestEngine/precomp.h @@ -17,3 +17,4 @@ #include "TestEngine.h" #include "ReloadEngine.h" #include "ShutdownEngine.h" +#include "WaitForQuitEngine.h" diff --git a/src/test/examples/WPFCoreMBA/AssemblyInfo.cs b/src/test/examples/WPFCoreMBA/AssemblyInfo.cs new file mode 100644 index 00000000..03a5c7fa --- /dev/null +++ b/src/test/examples/WPFCoreMBA/AssemblyInfo.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +using System.Windows; + +[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) +)] diff --git a/src/test/examples/WPFCoreMBA/Example.WPFCoreMBA.csproj b/src/test/examples/WPFCoreMBA/Example.WPFCoreMBA.csproj new file mode 100644 index 00000000..3b559f9b --- /dev/null +++ b/src/test/examples/WPFCoreMBA/Example.WPFCoreMBA.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + win-x86;win-x64 + true + WPF .NET Core MBA + true + + + + + + + + \ No newline at end of file diff --git a/src/test/examples/WPFCoreMBA/MainWindow.xaml b/src/test/examples/WPFCoreMBA/MainWindow.xaml new file mode 100644 index 00000000..40a27a06 --- /dev/null +++ b/src/test/examples/WPFCoreMBA/MainWindow.xaml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/src/test/examples/WPFCoreMBA/MainWindow.xaml.cs b/src/test/examples/WPFCoreMBA/MainWindow.xaml.cs new file mode 100644 index 00000000..4f61b807 --- /dev/null +++ b/src/test/examples/WPFCoreMBA/MainWindow.xaml.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace Example.WPFCoreMBA +{ + using System.Windows; + + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + this.InitializeComponent(); + } + } +} diff --git a/src/test/examples/WPFCoreMBA/WPFCoreBA.cs b/src/test/examples/WPFCoreMBA/WPFCoreBA.cs new file mode 100644 index 00000000..d50be813 --- /dev/null +++ b/src/test/examples/WPFCoreMBA/WPFCoreBA.cs @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace Example.WPFCoreMBA +{ + using System.Windows.Threading; + using WixToolset.Mba.Core; + + public class WPFCoreBA : BootstrapperApplication + { + public WPFCoreBA(IEngine engine) + : base(engine) + { + } + + public Dispatcher BADispatcher { get; private set; } + + protected override void Run() + { + this.BADispatcher = Dispatcher.CurrentDispatcher; + var window = new MainWindow(); + window.Closed += (s, e) => this.BADispatcher.InvokeShutdown(); + //window.Show(); + //Dispatcher.Run(); + //this.engine.Quit(0); + } + + protected override void OnStartup(StartupEventArgs args) + { + base.OnStartup(args); + + this.engine.Log(LogLevel.Standard, nameof(WPFCoreBA)); + } + + protected override void OnShutdown(ShutdownEventArgs args) + { + base.OnShutdown(args); + + var message = "Shutdown," + args.Action.ToString() + "," + args.HResult.ToString(); + this.engine.Log(LogLevel.Standard, message); + } + } +} diff --git a/src/test/examples/WPFCoreMBA/WPFCoreBAFactory.cs b/src/test/examples/WPFCoreMBA/WPFCoreBAFactory.cs new file mode 100644 index 00000000..a3ccdf9f --- /dev/null +++ b/src/test/examples/WPFCoreMBA/WPFCoreBAFactory.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +[assembly: WixToolset.Mba.Core.BootstrapperApplicationFactory(typeof(Example.WPFCoreMBA.WPFCoreBAFactory))] +namespace Example.WPFCoreMBA +{ + using WixToolset.Mba.Core; + + public class WPFCoreBAFactory : 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 WPFCoreBA(engine); + } + } +} -- cgit v1.2.3-55-g6feb