From e9fc7df426b9943143e5db40b822bfd7f97cebb5 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 24 Mar 2022 20:31:13 -0700 Subject: [PATCH 01/16] On error in MddBootstrapIntialize log to EventLog and optionally DebugBreak, FailFast and/or prompt to install --- .../MddBootstrap.cpp | 193 +++++++++++++++++- .../MddBootstrap.h | 42 ++++ .../WindowsAppRuntime.Bootstrap.def | 1 + 3 files changed, 232 insertions(+), 4 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index fca34d048f..8080d5aa34 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -12,6 +12,10 @@ #include +HRESULT _MddBootstrapInitialize( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) noexcept; void VerifyInitializationIsCompatible( UINT32 majorMinorVersion, PCWSTR versionTag, @@ -54,6 +58,16 @@ void FindDDLMViaEnumeration( std::wstring& ddlmPackageFamilyName, std::wstring& ddlmPackageFullName); CLSID GetClsid(const winrt::Windows::ApplicationModel::AppExtensions::AppExtension& appExtension); +bool IsOptionEnabled(PCWSTR name); +HRESULT MddBootstrapInitialize_Log( + HRESULT hrInitialize, + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) noexcept; +HRESULT MddBootstrapInitialize_ShowUI( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion); static std::mutex g_initializationLock; static std::atomic g_initializationCount{}; @@ -74,11 +88,61 @@ static std::wstring g_test_ddlmPackagePublisherId; STDAPI MddBootstrapInitialize( UINT32 majorMinorVersion, PCWSTR versionTag, - PACKAGE_VERSION minVersion) noexcept try + PACKAGE_VERSION minVersion) noexcept +{ + return MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, MddBootstrapInitializeOptions_None); +} + +STDAPI MddBootstrapInitialize2( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion, + MddBootstrapInitializeOptions options) noexcept try { // Dynamic Dependencies Bootstrap API requires a non-packaged process LOG_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), AppModel::Identity::IsPackagedProcess()); + // Are we already initialized? + const auto hr{ _MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion) }; + if (FAILED(hr)) + { + LOG_IF_FAILED(MddBootstrapInitialize_Log(hr, majorMinorVersion, versionTag, minVersion)); + + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_DebugBreak) || + (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached) && IsDebuggerPresent()) || + IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_DEBUGBREAK")) + { + DebugBreak(); + } + + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnNoMatch_ShowUI) || + IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_SHOWUI")) + { + LOG_IF_FAILED(MddBootstrapInitialize_ShowUI(majorMinorVersion, versionTag, minVersion)); + } + + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_FailFast) || + IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_FAILFAST")) + { + FAIL_FAST_HR_MSG(hr, + "Bootstrap initialize(0x%08X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision); + } + RETURN_HR(hr); + } + + // Success! + ++g_initializationCount; + return S_OK; +} +CATCH_RETURN(); + +HRESULT _MddBootstrapInitialize( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) noexcept try +{ // Are we already initialized? auto lock{ std::lock_guard(g_initializationLock) }; if (g_initializationCount > 0) @@ -91,9 +155,6 @@ STDAPI MddBootstrapInitialize( // First to the key! Do the initialization FirstTimeInitialization(majorMinorVersion, versionTag, minVersion); } - - // Success! - ++g_initializationCount; return S_OK; } CATCH_RETURN(); @@ -815,3 +876,127 @@ CLSID GetClsid(const winrt::Windows::ApplicationModel::AppExtensions::AppExtensi THROW_IF_WIN32_ERROR(UuidFromStringW(textRpcString, &clsid)); return clsid; } + +bool IsOptionEnabled(PCWSTR name) +{ + WCHAR value[1 + 1]{}; + if (GetEnvironmentVariableW(name, value, ARRAYSIZE(value)) == 1) + { + if (*value == L'0') + { + return false; + } + else if (*value == L'1') + { + return true; + } + } + return false; +} + +HRESULT MddBootstrapInitialize_Log( + HRESULT hrInitialize, + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) noexcept try +{ + HANDLE hEventLog{ RegisterEventSourceW(nullptr, L"Windows App Runtime") }; + RETURN_LAST_ERROR_IF_NULL(hEventLog); + + const DWORD c_eventId{ static_cast(hrInitialize) }; + PCWSTR message1{ L"Windows App Runtime" }; + WCHAR message2[1024]{}; + PCWSTR message2Format{ L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.%hu%s (MSIX packages version >= %hu.%hu.%hu.%hu)" }; + const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; + const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; + WCHAR formattedVersionTag[64]{}; + if (versionTag && (versionTag[0] != L'\0')) + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(formattedVersionTag, ARRAYSIZE(formattedVersionTag), L"-%s", versionTag)); + } + FAIL_FAST_IF_FAILED(StringCchPrintfW(message2, ARRAYSIZE(message2), message2Format, + hrInitialize, majorVersion, minorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + PCWSTR strings[2]{ message1, message2 }; + LOG_IF_WIN32_BOOL_FALSE(ReportEventW(hEventLog, EVENTLOG_ERROR_TYPE, 0, c_eventId, nullptr, ARRAYSIZE(strings), 0, strings, nullptr)); + + DeregisterEventSource(hEventLog); + + return S_OK; +} +CATCH_RETURN() + +HRESULT MddBootstrapInitialize_ShowUI( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) +{ + // Get the message caption + PCWSTR caption{}; + wil::unique_cotaskmem_string captionString; + WCHAR captionOnError[100]{}; + try + { + PCWSTR executable{}; + wil::unique_cotaskmem_string module; + auto hr{ LOG_IF_FAILED(wil::GetModuleFileNameW(nullptr, module)) }; + if (SUCCEEDED(hr)) + { + auto delimiter{ wcsrchr(module.get(), L'\\') }; + if (delimiter) + { + executable = delimiter + 1; + } + else + { + executable = module.get(); + } + PCWSTR captionSuffix{ L"This application could not be started" }; + captionString = wil::str_printf(L"%s - %s", executable, captionSuffix); + caption = captionString.get(); + } + } + catch (...) + { + } + if (!caption) + { + LOG_IF_FAILED(StringCchPrintfW(captionOnError, ARRAYSIZE(captionOnError), + L" - This application could not be started", + GetCurrentProcessId())); + caption = captionOnError; + } + + // Get the message body + WCHAR text[1024]{}; + PCWSTR textFormat{ L"This application requires the Windows App Runtime\n" + L" Version %hu.%hu%s\n" + L" (MSIX packages version >= %hu.%hu.%hu.%hu)\n" + L"\n" + L"Do you want to install a compatible Windows App Runtime now?" + }; + const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; + const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; + WCHAR formattedVersionTag[64]{}; + if (versionTag && (versionTag[0] != L'\0')) + { + FAIL_FAST_IF_FAILED(StringCchPrintfW(formattedVersionTag, ARRAYSIZE(formattedVersionTag), L"-%s", versionTag)); + } + FAIL_FAST_IF_FAILED(StringCchPrintfW(text, ARRAYSIZE(text), textFormat, + majorVersion, minorVersion, formattedVersionTag, + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision)); + + // Show the prompt + const auto yesno{ MessageBoxW(nullptr, text, caption, MB_YESNO | MB_ICONERROR) }; + if (yesno == IDYES) + { + SHELLEXECUTEINFOW sei{}; + sei.cbSize = sizeof(sei); + sei.lpVerb = L"open"; + sei.lpFile = L"https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/downloads"; + //TODO:Replace with https://aka.ms/windowsappsdk/./latest/windowsappruntimeinstall-.exe + sei.nShow = SW_SHOWNORMAL; + LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&sei)); + } + return S_OK; +} diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index ee7f38b461..ea62abf802 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -25,6 +25,48 @@ STDAPI MddBootstrapInitialize( PCWSTR versionTag, PACKAGE_VERSION minVersion) noexcept; +/// Options for MddBootstrapInitialize() +typedef enum MddBootstrapInitializeOptions +{ + /// Default behavior + MddBootstrapInitializeOptions_None = 0, + + /// If not successful call DebugBreak() + MddBootstrapInitializeOptions_OnError_DebugBreak = 0x0001, + + /// If not successful call DebugBreak() if a debugger is attached to the process + MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached = 0x0002, + + /// If not successful perform a fail-fast + MddBootstrapInitializeOptions_OnError_FailFast = 0x0002, + + /// If a compatible Windows App Runtime framework package is not found show UI + MddBootstrapInitializeOptions_OnNoMatch_ShowUI = 0x0004, +} MddBootstrapInitializeOptions; +#if defined(__cplusplus) +DEFINE_ENUM_FLAG_OPERATORS(MddBootstrapInitializeOptions) +#endif // defined(__cplusplus) + +/// Initialize the calling process to use Windows App Runtime framework package. +/// +/// Find a Windows App Runtime framework package meeting the criteria and make it available +/// for use by the current process. If multiple packages meet the criteria the best +/// candidate is selected. +/// +/// If called multiple times the parameters must be compatible with the framework package +/// resolved by the first initialization call (i.e. the framework package currently in use). +/// If the request is not compatible with the framework package currently in use +/// the API fails and an error is returned. +/// +/// @param majorMinorVersion the major and minor version to use, e..g 0x00010002 for Major.Minor=1.2 +/// @param versionTag the version pre-release identifier, or NULL if none. +/// @param minVersion the minimum version to use +STDAPI MddBootstrapInitialize2( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion, + MddBootstrapInitializeOptions options) noexcept; + /// Undo the changes made by MddBoostrapInitialize(). /// /// @warning Packages made available via MddBootstrapInitialize() and diff --git a/dev/WindowsAppRuntime_BootstrapDLL/WindowsAppRuntime.Bootstrap.def b/dev/WindowsAppRuntime_BootstrapDLL/WindowsAppRuntime.Bootstrap.def index 42e6425dab..bde4458d72 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/WindowsAppRuntime.Bootstrap.def +++ b/dev/WindowsAppRuntime_BootstrapDLL/WindowsAppRuntime.Bootstrap.def @@ -3,5 +3,6 @@ EXPORTS MddBootstrapInitialize + MddBootstrapInitialize2 MddBootstrapShutdown MddBootstrapTestInitialize From 16fff4cd5f2fb25ee59a111575c9513f9550a8aa Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 24 Mar 2022 20:33:53 -0700 Subject: [PATCH 02/16] Added ShowUI to C++ auto-initializer. --- dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp | 2 ++ .../MddBootstrapAutoInitializer.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 8080d5aa34..93def1c6bd 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -931,6 +931,8 @@ HRESULT MddBootstrapInitialize_ShowUI( PCWSTR versionTag, PACKAGE_VERSION minVersion) { + //TODO: Show this if ERROR_NO_MATCH vs simpler MessageBox("ERROR 0xN in Bootstrapper initialize", MB_OK) ? + // Get the message caption PCWSTR caption{}; wil::unique_cotaskmem_string captionString; diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp index 305f31b2e1..7bb2be04f1 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp @@ -26,7 +26,8 @@ namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap const UINT32 c_majorMinorVersion{ WINDOWSAPPSDK_RELEASE_MAJORMINOR }; PCWSTR c_versionTag{ WINDOWSAPPSDK_RELEASE_VERSION_TAG_W }; const PACKAGE_VERSION c_minVersion{ WINDOWSAPPSDK_RUNTIME_VERSION_UINT64 }; - const HRESULT hr{ ::MddBootstrapInitialize(c_majorMinorVersion, c_versionTag, c_minVersion) }; + const auto c_options{ MddBootstrapInitializeOptions_OnNoMatch_ShowUI }; + const HRESULT hr{ ::MddBootstrapInitialize2(c_majorMinorVersion, c_versionTag, c_minVersion, c_options) }; if (FAILED(hr)) { exit(hr); From 261c043f75e5e3a407413a7c828ebbbd87bb95f5 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Fri, 25 Mar 2022 14:54:09 -0700 Subject: [PATCH 03/16] Remove hardcoded language tag in URL Co-authored-by: Rafael Rivera --- dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 93def1c6bd..4a32be1aff 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -995,7 +995,7 @@ HRESULT MddBootstrapInitialize_ShowUI( SHELLEXECUTEINFOW sei{}; sei.cbSize = sizeof(sei); sei.lpVerb = L"open"; - sei.lpFile = L"https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/downloads"; + sei.lpFile = L"https://docs.microsoft.com/windows/apps/windows-app-sdk/downloads"; //TODO:Replace with https://aka.ms/windowsappsdk/./latest/windowsappruntimeinstall-.exe sei.nShow = SW_SHOWNORMAL; LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&sei)); From aa31e2d647da539449469bfed0c6a8a93171336e Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 28 Mar 2022 12:00:10 -0700 Subject: [PATCH 04/16] Incorporated feedback --- dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 93def1c6bd..912548f377 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -906,7 +906,7 @@ HRESULT MddBootstrapInitialize_Log( const DWORD c_eventId{ static_cast(hrInitialize) }; PCWSTR message1{ L"Windows App Runtime" }; WCHAR message2[1024]{}; - PCWSTR message2Format{ L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.%hu%s (MSIX packages version >= %hu.%hu.%hu.%hu)" }; + PCWSTR message2Format{ L"ERROR 0x%08X: Bootstrapper initialization failed while looking for version %hu.%hu%s (MSIX package version >= %hu.%hu.%hu.%hu)" }; const UINT16 majorVersion{ HIWORD(majorMinorVersion) }; const UINT16 minorVersion{ LOWORD(majorMinorVersion) }; WCHAR formattedVersionTag[64]{}; @@ -973,7 +973,7 @@ HRESULT MddBootstrapInitialize_ShowUI( WCHAR text[1024]{}; PCWSTR textFormat{ L"This application requires the Windows App Runtime\n" L" Version %hu.%hu%s\n" - L" (MSIX packages version >= %hu.%hu.%hu.%hu)\n" + L" (MSIX package version >= %hu.%hu.%hu.%hu)\n" L"\n" L"Do you want to install a compatible Windows App Runtime now?" }; From 08fddd249cb9cfd19e7567516ddeaa0704408b03 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 28 Mar 2022 17:49:21 -0700 Subject: [PATCH 05/16] Update C++ AutoInitializer to use MddBootstrapInitialize2 with options override (for those who don't like the default) --- .../MddBootstrapAutoInitializer.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp index 7bb2be04f1..ab559c1768 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp @@ -21,13 +21,24 @@ namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap ::MddBootstrapShutdown(); } + constexpr static MddBootstrapInitializeOptions Options() + { +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS) + // #define MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS=options (e.g. =0x0012 or =18) + return static_cast(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS); +#else + // Default options for the auto-initializer + return MddBootstrapInitializeOptions_OnNoMatch_ShowUI; +#endif + } + static void Initialize() { const UINT32 c_majorMinorVersion{ WINDOWSAPPSDK_RELEASE_MAJORMINOR }; PCWSTR c_versionTag{ WINDOWSAPPSDK_RELEASE_VERSION_TAG_W }; const PACKAGE_VERSION c_minVersion{ WINDOWSAPPSDK_RUNTIME_VERSION_UINT64 }; - const auto c_options{ MddBootstrapInitializeOptions_OnNoMatch_ShowUI }; - const HRESULT hr{ ::MddBootstrapInitialize2(c_majorMinorVersion, c_versionTag, c_minVersion, c_options) }; + const auto c_options{ Options() }; + const HRESULT hr{ ::MddBootstrapInitialize2(c_majorMinorVersion, c_versionTag, c_minVersion, c_options }; if (FAILED(hr)) { exit(hr); From 268aef4eb255f6d98ddf0d1ff394a8ab01a26e31 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 28 Mar 2022 17:49:44 -0700 Subject: [PATCH 06/16] Add MddBootstrapInitializeOptions_OnPackageIdentity_NOP with tests --- .../MddBootstrap.cpp | 24 +++++-- .../MddBootstrap.h | 7 +- .../Test_Win32/TestMddBootstrap.cpp | 66 +++++++++++++++++++ 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 912548f377..2290a12cce 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -99,15 +99,27 @@ STDAPI MddBootstrapInitialize2( PACKAGE_VERSION minVersion, MddBootstrapInitializeOptions options) noexcept try { - // Dynamic Dependencies Bootstrap API requires a non-packaged process - LOG_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), AppModel::Identity::IsPackagedProcess()); - - // Are we already initialized? - const auto hr{ _MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion) }; + // Dynamic Dependencies Bootstrap API requires an unpackaged process? + HRESULT hr{}; + if (AppModel::Identity::IsPackagedProcess()) + { + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnPackageIdentity_NOP)) + { + // The process has package identity but that's OK. Do nothing + return S_OK; + } + hr = LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), "MddBootstrapInitialize called in a process with package identity"); + } + else + { + hr = _MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion); + } if (FAILED(hr)) { LOG_IF_FAILED(MddBootstrapInitialize_Log(hr, majorMinorVersion, versionTag, minVersion)); + // NOTE: IsDebuggerPresent()=TRUE if running under a debugger context. + // IsDebuggerPresent()=FALSE if not running under a debugger context, even if AEDebug is set. if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_DebugBreak) || (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached) && IsDebuggerPresent()) || IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_DEBUGBREAK")) @@ -995,7 +1007,7 @@ HRESULT MddBootstrapInitialize_ShowUI( SHELLEXECUTEINFOW sei{}; sei.cbSize = sizeof(sei); sei.lpVerb = L"open"; - sei.lpFile = L"https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/downloads"; + sei.lpFile = L"https://docs.microsoft.com/windows/apps/windows-app-sdk/downloads"; //TODO:Replace with https://aka.ms/windowsappsdk/./latest/windowsappruntimeinstall-.exe sei.nShow = SW_SHOWNORMAL; LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&sei)); diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index ea62abf802..45ce041a53 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -38,10 +38,13 @@ typedef enum MddBootstrapInitializeOptions MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached = 0x0002, /// If not successful perform a fail-fast - MddBootstrapInitializeOptions_OnError_FailFast = 0x0002, + MddBootstrapInitializeOptions_OnError_FailFast = 0x0004, /// If a compatible Windows App Runtime framework package is not found show UI - MddBootstrapInitializeOptions_OnNoMatch_ShowUI = 0x0004, + MddBootstrapInitializeOptions_OnNoMatch_ShowUI = 0x0008, + + /// Do nothing if the process has package identity + MddBootstrapInitializeOptions_OnPackageIdentity_NOP = 0x0010, } MddBootstrapInitializeOptions; #if defined(__cplusplus) DEFINE_ENUM_FLAG_OPERATORS(MddBootstrapInitializeOptions) diff --git a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp index 5f5f9277db..bad283e243 100644 --- a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp +++ b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp @@ -372,4 +372,70 @@ namespace Test::DynamicDependency } #endif }; + + class BootstrapPackagedTests + { + public: + BEGIN_TEST_CLASS(BootstrapPackagedTests) + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"UAP:NoSplashScreen", L"true") + TEST_CLASS_PROPERTY(L"UAP:RuntimeBehavior", L"PackagedClassicApp") + TEST_CLASS_PROPERTY(L"UAP:TrustLevel", L"MediumIL") + END_TEST_CLASS() + + TEST_CLASS_SETUP(Setup) + { + return BootstrapFixtures::Setup(); + } + + TEST_CLASS_CLEANUP(Cleanup) + { + return BootstrapFixtures::Cleanup(); + } + + TEST_METHOD(Initialize_Packaged_NotSupported) + { + VERIFY_ARE_EQUAL(S_OK, MddBootstrapTestInitialize(Test::Packages::DynamicDependencyLifetimeManager::c_PackageNamePrefix, Test::Packages::DynamicDependencyLifetimeManager::c_PackagePublisherId)); + + // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version + const UINT32 c_Version_MajorMinor{ Test::Packages::DynamicDependencyLifetimeManager::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion{}; + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); + } + + TEST_METHOD(Initialize_Packaged_NOP) + { + VERIFY_ARE_EQUAL(S_OK, MddBootstrapTestInitialize(Test::Packages::DynamicDependencyLifetimeManager::c_PackageNamePrefix, Test::Packages::DynamicDependencyLifetimeManager::c_PackagePublisherId)); + + // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version + const UINT32 c_Version_MajorMinor{ Test::Packages::DynamicDependencyLifetimeManager::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion{}; + const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOP }; + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); + + MddBootstrapShutdown(); + } + + TEST_METHOD(Initialize_Packaged_NOP_Multiple) + { + VERIFY_ARE_EQUAL(S_OK, MddBootstrapTestInitialize(Test::Packages::DynamicDependencyLifetimeManager::c_PackageNamePrefix, Test::Packages::DynamicDependencyLifetimeManager::c_PackagePublisherId)); + + // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version + const UINT32 c_Version_MajorMinor{ Test::Packages::DynamicDependencyLifetimeManager::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion{}; + const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOP }; + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); + + MddBootstrapShutdown(); + MddBootstrapShutdown(); + + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); + + MddBootstrapShutdown(); + } + }; } From 38f84715b5cd3a8d41f98b0cc8ad6c1f9a2441b1 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 28 Mar 2022 18:36:47 -0700 Subject: [PATCH 07/16] Moar tests. Fixed NOP/NOOP typo. Added C# support for InitializeOptions and use MddBootstrapInitialize2 --- .../Bootstrap.cs | 95 ++++++++++++++++--- .../MddBootstrap.cpp | 2 +- .../MddBootstrap.h | 72 ++++++++++---- .../Test_Win32/TestMddBootstrap.cpp | 4 +- .../TestMddBootstrapCppInitialize.cpp | 18 ++++ 5 files changed, 157 insertions(+), 34 deletions(-) diff --git a/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs b/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs index a36ce03a21..0c26b43799 100644 --- a/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs +++ b/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs @@ -66,11 +66,11 @@ public override string ToString() internal static class NativeMethods { - [DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", EntryPoint = "MddBootstrapInitialize", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] - internal static extern void MddBootstrapInitialize_Throw(uint majorMinorVersion, string versionTag, PackageVersion packageVersion); + [DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", EntryPoint = "MddBootstrapInitialize2", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + internal static extern void MddBootstrapInitialize2_Throw(uint majorMinorVersion, string versionTag, PackageVersion packageVersion, Bootstrap.InitializeOptions options); [DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] - internal static extern int MddBootstrapInitialize(uint majorMinorVersion, string versionTag, PackageVersion packageVersion); + internal static extern int MddBootstrapInitialize2(uint majorMinorVersion, string versionTag, PackageVersion packageVersion, Bootstrap.InitializeOptions options); [DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", ExactSpelling = true)] internal static extern void MddBootstrapShutdown(); @@ -79,17 +79,40 @@ internal static class NativeMethods // The Windows App SDK bootstrap initialization API. public class Bootstrap { + /// Options for Bootstrap initialization APIs. + public enum InitializeOptions : int + { + /// Default behavior + None = 0, + + /// If not successful call DebugBreak() + OnError_DebugBreak = 0x0001, + + /// If not successful call DebugBreak() if a debugger is attached to the process + OnError_DebugBreak_IfDebuggerAttached = 0x0002, + + /// If not successful perform a fail-fast + OnError_FailFast = 0x0004, + + /// If a compatible Windows App Runtime framework package is not found show UI + OnNoMatch_ShowUI = 0x0008, + + /// Do nothing (do not error) if the process has package identity + OnPackageIdentity_NOOP = 0x0010, + }; + /// Initialize the calling process to use Windows App SDK's framework package. /// /// Find a Windows App SDK framework package meeting the criteria and make it available /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// - /// This is equivalent to `Initialize(majorMinorVersion, null, new PackageVersion())`. + /// This is equivalent to `Initialize(majorMinorVersion, null, new PackageVersion(), InitializeOptions.None)`. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @see Initialize(uint, string) /// @see Initialize(uint, string, PackageVersion) + /// @see Initialize(uint, string, PackageVersion, InitializeOptions) /// @see Shutdown() public static void Initialize(uint majorMinorVersion) { @@ -102,12 +125,13 @@ public static void Initialize(uint majorMinorVersion) /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// - /// This is equivalent to `Initialize(majorMinorVersion, versionTag, new PackageVersion())`. + /// This is equivalent to `Initialize(majorMinorVersion, versionTag, new PackageVersion(), InitializeOptions.None)`. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @see Initialize(uint) /// @see Initialize(uint, string, PackageVersion) + /// @see Initialize(uint, string, PackageVersion, InitializeOptions) /// @see Shutdown() public static void Initialize(uint majorMinorVersion, string versionTag) { @@ -120,15 +144,37 @@ public static void Initialize(uint majorMinorVersion, string versionTag) /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// + /// This is equivalent to `Initialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None)`. + /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". - /// @param minVersion the minimum version to use + /// @param minVersion the minimum version to use. /// @see Initialize(uint) /// @see Initialize(uint, string) + /// @see Initialize(uint, string, PackageVersion, InitializeOptions) /// @see Shutdown() public static void Initialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion) { - NativeMethods.MddBootstrapInitialize_Throw(majorMinorVersion, versionTag, minVersion); + NativeMethods.MddBootstrapInitialize2_Throw(majorMinorVersion, versionTag, minVersion, InitializeOptions.None); + } + + /// Initialize the calling process to use Windows App SDK's framework package. + /// + /// Find a Windows App SDK framework package meeting the criteria and make it available + /// for use by the current process. If multiple packages meet the criteria the best + /// candidate is selected. + /// + /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). + /// @param versionTag version tag (if any), e.g. "preview1". + /// @param minVersion the minimum version to use. + /// @param options optional behavior. + /// @see Initialize(uint) + /// @see Initialize(uint, string) + /// @see Initialize(uint, string, PackageVersion) + /// @see Shutdown() + public static void Initialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, InitializeOptions options) + { + NativeMethods.MddBootstrapInitialize2_Throw(majorMinorVersion, versionTag, minVersion, options); } /// Initialize the calling process to use Windows App SDK's framework package. @@ -138,12 +184,12 @@ public static void Initialize(uint majorMinorVersion, string versionTag, Package /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// - /// This is equivalent to `TryInitialize(majorMinorVersion, null, new PackageVersion(), hresult)`. + /// This is equivalent to `TryInitialize(majorMinorVersion, null, new PackageVersion(), InitializeOptions.None, hresult)`. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @retval true if successful, otherwise false is returned. /// @see TryInitialize(uint, string, out int) - /// @see TryInitialize(uint, string, PackageVersion, out int) + /// @see TryInitialize(uint, string, PackageVersion, InitializeOptions, out int) /// @see Shutdown() public static bool TryInitialize(uint majorMinorVersion, out int hresult) { @@ -157,13 +203,14 @@ public static bool TryInitialize(uint majorMinorVersion, out int hresult) /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// - /// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, new PackageVersion(), hresult)`. + /// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, new PackageVersion(), InitializeOptions.None, hresult)`. /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @retval true if successful, otherwise false is returned. /// @see TryInitialize(uint, out int) /// @see TryInitialize(uint, string, PackageVersion, out int) + /// @see TryInitialize(uint, string, PackageVersion, InitializeOptions, out int) /// @see Shutdown() public static bool TryInitialize(uint majorMinorVersion, string versionTag, out int hresult) { @@ -178,17 +225,43 @@ public static bool TryInitialize(uint majorMinorVersion, string versionTag, out /// for use by the current process. If multiple packages meet the criteria the best /// candidate is selected. /// + /// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None, hresult)`. + /// /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use. + /// @param options optional behavior. /// @param hresult the error code if an error occurred. /// @retval true if successful, otherwise false is returned. /// @see TryInitialize(uint, out int) /// @see TryInitialize(uint, string, out int) + /// @see TryInitialize(uint, string, PackageVersion, out int) /// @see Shutdown() public static bool TryInitialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, out int hresult) { - hresult = NativeMethods.MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion); + return TryInitialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None, out hresult); + } + + /// Initialize the calling process to use Windows App SDK's framework package. + /// Failure returns false with the failure HRESULT in the hresult parameter. + /// + /// Find a Windows App SDK framework package meeting the criteria and make it available + /// for use by the current process. If multiple packages meet the criteria the best + /// candidate is selected. + /// + /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). + /// @param versionTag version tag (if any), e.g. "preview1". + /// @param minVersion the minimum version to use. + /// @param options optional behavior. + /// @param hresult the error code if an error occurred. + /// @retval true if successful, otherwise false is returned. + /// @see TryInitialize(uint, out int) + /// @see TryInitialize(uint, string, out int) + /// @see TryInitialize(uint, string, PackageVersion, out int) + /// @see Shutdown() + public static bool TryInitialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, InitializeOptions options, out int hresult) + { + hresult = NativeMethods.MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, options); return hresult >= 0; } diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 2290a12cce..b5bfa769bc 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -103,7 +103,7 @@ STDAPI MddBootstrapInitialize2( HRESULT hr{}; if (AppModel::Identity::IsPackagedProcess()) { - if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnPackageIdentity_NOP)) + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnPackageIdentity_NOOP)) { // The process has package identity but that's OK. Do nothing return S_OK; diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index 45ce041a53..a1ffa4ae5e 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -25,11 +25,11 @@ STDAPI MddBootstrapInitialize( PCWSTR versionTag, PACKAGE_VERSION minVersion) noexcept; -/// Options for MddBootstrapInitialize() +/// Options for Bootstrap initialization typedef enum MddBootstrapInitializeOptions { /// Default behavior - MddBootstrapInitializeOptions_None = 0, + MddBootstrapInitializeOptions_None = 0, /// If not successful call DebugBreak() MddBootstrapInitializeOptions_OnError_DebugBreak = 0x0001, @@ -43,8 +43,8 @@ typedef enum MddBootstrapInitializeOptions /// If a compatible Windows App Runtime framework package is not found show UI MddBootstrapInitializeOptions_OnNoMatch_ShowUI = 0x0008, - /// Do nothing if the process has package identity - MddBootstrapInitializeOptions_OnPackageIdentity_NOP = 0x0010, + /// Do nothing (do not error) if the process has package identity + MddBootstrapInitializeOptions_OnPackageIdentity_NOOP = 0x0010, } MddBootstrapInitializeOptions; #if defined(__cplusplus) DEFINE_ENUM_FLAG_OPERATORS(MddBootstrapInitializeOptions) @@ -72,7 +72,7 @@ STDAPI MddBootstrapInitialize2( /// Undo the changes made by MddBoostrapInitialize(). /// -/// @warning Packages made available via MddBootstrapInitialize() and +/// @warning Packages made available via MddBootstrapInitialize2() and /// the Dynamic Dependencies API should not be used after this call. STDAPI_(void) MddBootstrapShutdown() noexcept; @@ -148,7 +148,33 @@ namespace DynamicDependency::Bootstrap } using unique_mddbootstrapshutdown = std::unique_ptr; - /// Call MddBootstrapInitialize and aborts the process (via std::abort()) if it fails; + /// Options for Bootstrap initialization APIs. + /// @see InitializeFailFast(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + /// @see Initialize(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + /// @see InitializeNoThrow(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + enum class InitializeOptions + { + /// Default behavior + None = MddBootstrapInitializeOptions_None, + + /// If not successful call DebugBreak() + OnError_DebugBreak = MddBootstrapInitializeOptions_OnError_DebugBreak, + + /// If not successful call DebugBreak() if a debugger is attached to the process + OnError_DebugBreak_IfDebuggerAttached = MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached, + + /// If not successful perform a fail-fast + OnError_FailFast = MddBootstrapInitializeOptions_OnError_FailFast, + + /// If a compatible Windows App Runtime framework package is not found show UI + OnNoMatch_ShowUI = MddBootstrapInitializeOptions_OnNoMatch_ShowUI, + + /// Do nothing (do not error) if the process has package identity + OnPackageIdentity_NOOP = MddBootstrapInitializeOptions_OnPackageIdentity_NOOP, + }; + DEFINE_ENUM_FLAG_OPERATORS(InitializeOptions) + + /// Call MddBootstrapInitialize2() and aborts the process (via std::abort()) if it fails; /// returns an RAII object that reverts the initialization on success. /// /// Initialize the calling process to use Windows App SDK's framework package. @@ -160,8 +186,9 @@ namespace DynamicDependency::Bootstrap /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use - /// @see Initialize(uint32_t, PCWSTR, PackageVersion) - /// @see InitializeNoThrow(uint32_t, PCWSTR, PackageVersion) + /// @param options optional behavior + /// @see Initialize(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + /// @see InitializeNoThrow(uint32_t, PCWSTR, PackageVersion, InitializeOptions) /// @see Shutdown() /// ~~~~~ /// #include @@ -183,9 +210,10 @@ namespace DynamicDependency::Bootstrap [[nodiscard]] inline unique_mddbootstrapshutdown InitializeFailFast( uint32_t majorMinorVersion = WINDOWSAPPSDK_RELEASE_MAJORMINOR, PCWSTR versionTag = WINDOWSAPPSDK_RELEASE_VERSION_TAG_W, - PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) + PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64, + InitializeOptions options = ::Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap::InitializeOptions::None) { - const auto hr{ ::MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion) }; + const auto hr{ ::MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, static_cast(options)) }; if (FAILED(hr)) { std::abort(); @@ -194,7 +222,7 @@ namespace DynamicDependency::Bootstrap } #if defined(_CPPUNWIND) && defined(WINRT_BASE_H) - /// Call MddBootstrapInitialize and throws an exception if it fails; + /// Call MddBootstrapInitialize2() and throws an exception if it fails; /// returns an RAII object that reverts the initialization on success. /// /// Initialize the calling process to use Windows App SDK's framework package. @@ -206,8 +234,9 @@ namespace DynamicDependency::Bootstrap /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use - /// @see Initialize_failfast(uint32_t, PCWSTR, PackageVersion) - /// @see Initialize_nothrow(uint32_t, PCWSTR, PackageVersion) + /// @param options optional behavior + /// @see Initialize_failfast(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + /// @see Initialize_nothrow(uint32_t, PCWSTR, PackageVersion, InitializeOptions) /// @see Shutdown() /// @exception winrt::hresult_error thrown if intialization fails; see code() for more details. /// ~~~~~ @@ -241,14 +270,15 @@ namespace DynamicDependency::Bootstrap [[nodiscard]] inline unique_mddbootstrapshutdown Initialize( uint32_t majorMinorVersion = WINDOWSAPPSDK_RELEASE_MAJORMINOR, PCWSTR versionTag = WINDOWSAPPSDK_RELEASE_VERSION_TAG_W, - PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) + PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64, + InitializeOptions options = ::Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap::InitializeOptions::None) { - winrt::check_hresult(::MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion)); + winrt::check_hresult(::MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, static_cast(options))); return unique_mddbootstrapshutdown(reinterpret_cast(1)); } #endif // defined(_CPPUNWIND) && defined(WINRT_BASE_H) - /// Call MddBootstrapInitialize and returns a failure HRESULT if it fails. + /// Call MddBootstrapInitialize2() and returns a failure HRESULT if it fails. /// /// Initialize the calling process to use Windows App SDK's framework package. /// @@ -259,8 +289,9 @@ namespace DynamicDependency::Bootstrap /// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002). /// @param versionTag version tag (if any), e.g. "preview1". /// @param minVersion the minimum version to use - /// @see InitializeFailFast(uint32_t, PCWSTR, PackageVersion) - /// @see Initialize(uint32_t, PCWSTR, PackageVersion) + /// @param options optional behavior + /// @see InitializeFailFast(uint32_t, PCWSTR, PackageVersion, InitializeOptions) + /// @see Initialize(uint32_t, PCWSTR, PackageVersion, InitializeOptions) /// @see Shutdown() /// ~~~~~ /// #include @@ -288,9 +319,10 @@ namespace DynamicDependency::Bootstrap inline HRESULT InitializeNoThrow( uint32_t majorMinorVersion = WINDOWSAPPSDK_RELEASE_MAJORMINOR, PCWSTR versionTag = WINDOWSAPPSDK_RELEASE_VERSION_TAG_W, - PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) + PackageVersion minVersion = WINDOWSAPPSDK_RUNTIME_VERSION_UINT64, + InitializeOptions options = ::Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap::InitializeOptions::None) { - return ::MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion); + return ::MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, static_cast(options)); } } #endif // defined(WINDOWSAPPSDK_RELEASE_MAJORMINOR) && defined(WINDOWSAPPSDK_RELEASE_VERSION_TAG_W) && defined(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) diff --git a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp index bad283e243..36aa8ace87 100644 --- a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp +++ b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp @@ -412,7 +412,7 @@ namespace Test::DynamicDependency // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version const UINT32 c_Version_MajorMinor{ Test::Packages::DynamicDependencyLifetimeManager::c_Version_MajorMinor }; const PACKAGE_VERSION c_minVersion{}; - const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOP }; + const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOOP }; VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); MddBootstrapShutdown(); @@ -425,7 +425,7 @@ namespace Test::DynamicDependency // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version const UINT32 c_Version_MajorMinor{ Test::Packages::DynamicDependencyLifetimeManager::c_Version_MajorMinor }; const PACKAGE_VERSION c_minVersion{}; - const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOP }; + const auto c_options{ MddBootstrapInitializeOptions_OnPackageIdentity_NOOP }; VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize2(c_Version_MajorMinor, nullptr, c_minVersion, c_options)); diff --git a/test/DynamicDependency/Test_Win32/TestMddBootstrapCppInitialize.cpp b/test/DynamicDependency/Test_Win32/TestMddBootstrapCppInitialize.cpp index b22b624ddd..c23025d953 100644 --- a/test/DynamicDependency/Test_Win32/TestMddBootstrapCppInitialize.cpp +++ b/test/DynamicDependency/Test_Win32/TestMddBootstrapCppInitialize.cpp @@ -31,23 +31,41 @@ HRESULT TestCompile() AM::PackageVersion pv7(0x0001000200030004ul); AM::PackageVersion pv8(0x0001000200030004ull); + B::InitializeOptions opt0{}; + B::InitializeOptions opt1{ B::InitializeOptions::None }; + B::InitializeOptions opt2{ B::InitializeOptions::OnError_DebugBreak | + B::InitializeOptions::OnError_DebugBreak_IfDebuggerAttached | + B::InitializeOptions::OnError_FailFast | + B::InitializeOptions::OnNoMatch_ShowUI | + B::InitializeOptions::OnPackageIdentity_NOOP + }; + auto f1 = B::InitializeFailFast(); auto f2 = B::InitializeFailFast(0x12345678); auto f3 = B::InitializeFailFast(0x12345678, L"versiontag"); auto f4 = B::InitializeFailFast(0x12345678, L"versiontag", AM::PackageVersion(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64)); auto f5 = B::InitializeFailFast(0x12345678, L"versiontag", pv0); + auto f6 = B::InitializeFailFast(0x12345678, L"versiontag", pv0, opt0); + auto f7 = B::InitializeFailFast(0x12345678, L"versiontag", pv0, opt1); + auto f8 = B::InitializeFailFast(0x12345678, L"versiontag", pv0, opt2); auto t1 = B::Initialize(); auto t2 = B::Initialize(0x12345678); auto t3 = B::Initialize(0x12345678, L"versiontag"); auto t4 = B::Initialize(0x12345678, L"versiontag", AM::PackageVersion(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64)); auto t5 = B::Initialize(0x12345678, L"versiontag", pv0); + auto t6 = B::Initialize(0x12345678, L"versiontag", pv0, opt0); + auto t7 = B::Initialize(0x12345678, L"versiontag", pv0, opt1); + auto t8 = B::Initialize(0x12345678, L"versiontag", pv0, opt2); const auto h1{ B::InitializeNoThrow() }; const auto h2{ B::InitializeNoThrow(0x12345678) }; const auto h3{ B::InitializeNoThrow(0x12345678, L"versiontag") }; const auto h4{ B::InitializeNoThrow(0x12345678, L"versiontag", AM::PackageVersion(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64)) }; const auto h5{ B::InitializeNoThrow(0x12345678, L"versiontag", pv0) }; + const auto h6{ B::InitializeNoThrow(0x12345678, L"versiontag", pv0, opt0) }; + const auto h7{ B::InitializeNoThrow(0x12345678, L"versiontag", pv0, opt1) }; + const auto h8{ B::InitializeNoThrow(0x12345678, L"versiontag", pv0, opt2) }; return S_OK; } From 98eb12775b2de496a21f41bb6510c819c5442cf6 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Mon, 28 Mar 2022 20:58:13 -0700 Subject: [PATCH 08/16] Let's try that. C# AutoInitializer options override --- .../MddBootstrapAutoInitializer.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs index ab20d5dd5b..bb790b9829 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs @@ -11,14 +11,27 @@ internal static void AccessWindowsAppSDK() uint majorMinorVersion = global::Microsoft.WindowsAppSDK.Release.MajorMinor; string versionTag = global::Microsoft.WindowsAppSDK.Release.VersionTag; var minVersion = new PackageVersion(global::Microsoft.WindowsAppSDK.Runtime.Version.UInt64); + var options = Options; try { - global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(majorMinorVersion, versionTag, minVersion); + global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(majorMinorVersion, versionTag, minVersion, options); } catch (global::System.Exception e) { global::System.Environment.FailFast(e.Message); } } + + internal static global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions Options + { + get + { +#ifdef MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTOINITIALIZER_OPTIONS_OVERRIDE + return Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.AutoInitializer.InitializeOptions.Override.GetDefault(); +#else + return Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnNoMatch_ShowUI; +#endif + } + } } } From ad1579d8422fcecf4bf5054a6c14d3c4768fcce3 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Tue, 29 Mar 2022 22:52:01 -0700 Subject: [PATCH 09/16] Added build option to control auto-initializer (WindowsAppSDKBootstrapAutoInitialize=false, default=true). Added boolean control over the new options e.g. true --- ...crosoft.WindowsAppSDK.Bootstrap.CS.targets | 22 ++++++++-- ...ndowsAppSDK-Nuget-Native.Bootstrap.targets | 24 ++++++++--- .../MddBootstrapAutoInitializer.cpp | 40 ++++++++++++++++--- .../MddBootstrapAutoInitializer.cs | 39 ++++++++++++++++-- 4 files changed, 108 insertions(+), 17 deletions(-) diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets index f2c0c619f9..338fa3cc2d 100644 --- a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets +++ b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets @@ -1,7 +1,23 @@ - + - + + true + + + + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP + + + diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets index f2201a59b9..57bc9b0bf7 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets @@ -1,11 +1,23 @@ - + - + + true + + + - - NotUsing - + + NotUsing + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP;%(PreprocessorDefinitions) + diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp index ab559c1768..3f70659786 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp @@ -7,6 +7,18 @@ #include #include +// If any options are defined use them, else use the default +#if !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP) +// No options specified! Use the default +#define MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT +#endif + namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap { struct AutoInitialize @@ -23,13 +35,31 @@ namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap constexpr static MddBootstrapInitializeOptions Options() { -#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS) - // #define MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS=options (e.g. =0x0012 or =18) - return static_cast(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_INITIALIZE_OPTIONS); -#else - // Default options for the auto-initializer +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT) + // Use the default options return MddBootstrapInitializeOptions_OnNoMatch_ShowUI; +#elif defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE) + // No options! + return MddBootstrapInitializeOptions_None; +#else + // Use the specified options + return MddBootstrapInitializeOptions_None +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK) + | MddBootstrapInitializeOptions_OnError_DebugBreak +#endif +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED) + | MddBootstrapInitializeOptions_OnError_DebugBreak_IfDebuggerAttached +#endif +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST) + | MddBootstrapInitializeOptions_OnError_FailFast +#endif +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI) + | MddBootstrapInitializeOptions_OnNoMatch_ShowUI +#endif +#if defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP) + | MddBootstrapInitializeOptions_OnPackageIdentity_NOOP #endif + ; } static void Initialize() diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs index bb790b9829..b64d352f9a 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs @@ -1,6 +1,18 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. +// If any options are defined use them, else use the default +#if !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI) && \ + !defined(MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP) +// No options specified! Use the default +#define MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT +#endif + namespace Microsoft.Windows.ApplicationModel.DynamicDependency.BootstrapCS { class AutoInitialize @@ -26,10 +38,31 @@ internal static void AccessWindowsAppSDK() { get { -#ifdef MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTOINITIALIZER_OPTIONS_OVERRIDE - return Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.AutoInitializer.InitializeOptions.Override.GetDefault(); +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT + // Use the default options + return global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnNoMatch_ShowUI; +#elif MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE + // No options! + return global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.None; #else - return Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnNoMatch_ShowUI; + // Use the specified options + var options = global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.None; +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK + options |= global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnError_DebugBreak; +#endif +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED + options | global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnError_DebugBreak_IfDebuggerAttached; +#endif +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST + options | global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnError_FailFast; +#endif +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI + options | global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnNoMatch_ShowUI; +#endif +#if MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP + options | global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.InitializeOptions.OnPackageIdentity_NOOP; +#endif + return options; #endif } } From 3dd67077d137cf363aff542f3bd698ce409665f4 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Tue, 29 Mar 2022 23:23:05 -0700 Subject: [PATCH 10/16] Minnor reformatting and cleanup --- .../Bootstrap.cs | 4 +- .../MddBootstrap.h | 42 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs b/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs index 0c26b43799..413864eabd 100644 --- a/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs +++ b/dev/Bootstrap/CS/Microsoft.WindowsAppRuntime.Bootstrap.Net/Bootstrap.cs @@ -99,7 +99,7 @@ public enum InitializeOptions : int /// Do nothing (do not error) if the process has package identity OnPackageIdentity_NOOP = 0x0010, - }; + } /// Initialize the calling process to use Windows App SDK's framework package. /// @@ -272,9 +272,11 @@ public static bool TryInitialize(uint majorMinorVersion, string versionTag, Pack /// @see Initialize(uint) /// @see Initialize(uint, string) /// @see Initialize(uint, string, PackageVersion) + /// @see Initialize(uint, string, PackageVersion, InitializeOptions options) /// @see TryInitialize(uint, out int) /// @see TryInitialize(uint, string, out int) /// @see TryInitialize(uint, string, PackageVersion, out int) + /// @see TryInitialize(uint, string, PackageVersion, InitializeOptions options, out int) public static void Shutdown() { NativeMethods.MddBootstrapShutdown(); diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index a1ffa4ae5e..9581bc4a88 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -6,25 +6,6 @@ #include -/// Initialize the calling process to use Windows App Runtime framework package. -/// -/// Find a Windows App Runtime framework package meeting the criteria and make it available -/// for use by the current process. If multiple packages meet the criteria the best -/// candidate is selected. -/// -/// If called multiple times the parameters must be compatible with the framework package -/// resolved by the first initialization call (i.e. the framework package currently in use). -/// If the request is not compatible with the framework package currently in use -/// the API fails and an error is returned. -/// -/// @param majorMinorVersion the major and minor version to use, e..g 0x00010002 for Major.Minor=1.2 -/// @param versionTag the version pre-release identifier, or NULL if none. -/// @param minVersion the minimum version to use -STDAPI MddBootstrapInitialize( - UINT32 majorMinorVersion, - PCWSTR versionTag, - PACKAGE_VERSION minVersion) noexcept; - /// Options for Bootstrap initialization typedef enum MddBootstrapInitializeOptions { @@ -50,6 +31,25 @@ typedef enum MddBootstrapInitializeOptions DEFINE_ENUM_FLAG_OPERATORS(MddBootstrapInitializeOptions) #endif // defined(__cplusplus) +/// Initialize the calling process to use Windows App Runtime framework package. +/// +/// Find a Windows App Runtime framework package meeting the criteria and make it available +/// for use by the current process. If multiple packages meet the criteria the best +/// candidate is selected. +/// +/// If called multiple times the parameters must be compatible with the framework package +/// resolved by the first initialization call (i.e. the framework package currently in use). +/// If the request is not compatible with the framework package currently in use +/// the API fails and an error is returned. +/// +/// @param majorMinorVersion the major and minor version to use, e..g 0x00010002 for Major.Minor=1.2 +/// @param versionTag the version pre-release identifier, or NULL if none. +/// @param minVersion the minimum version to use +STDAPI MddBootstrapInitialize( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) noexcept; + /// Initialize the calling process to use Windows App Runtime framework package. /// /// Find a Windows App Runtime framework package meeting the criteria and make it available @@ -130,7 +130,6 @@ class PackageVersion : public PACKAGE_VERSION #endif }; -#if defined(WINDOWSAPPSDK_RELEASE_MAJORMINOR) && defined(WINDOWSAPPSDK_RELEASE_VERSION_TAG_W) && defined(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) namespace DynamicDependency::Bootstrap { // Automate Boostrap shutdown when leaving scope @@ -325,9 +324,8 @@ namespace DynamicDependency::Bootstrap return ::MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, static_cast(options)); } } -#endif // defined(WINDOWSAPPSDK_RELEASE_MAJORMINOR) && defined(WINDOWSAPPSDK_RELEASE_VERSION_TAG_W) && defined(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) } -#endif // defined(WINDOWSAPPSDK_RELEASE_MAJORMINOR) && defined(WINDOWSAPPSDK_RELEASE_VERSION_TAG_W) && defined()WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) +#endif // defined(WINDOWSAPPSDK_RELEASE_MAJORMINOR) && defined(WINDOWSAPPSDK_RELEASE_VERSION_TAG_W) && defined(WINDOWSAPPSDK_RUNTIME_VERSION_UINT64) #endif // defined(__cplusplus) #endif // MDDBOOTSTRAP_H From dc1542efd8ce46653650cb4a316743886f526ec7 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Wed, 30 Mar 2022 12:38:30 -0700 Subject: [PATCH 11/16] Changed to use TryInitialize and Exit (instead of throwing Initialize and FailFast) for less misleading error symptoms --- .../MddBootstrapAutoInitializer.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs index bb790b9829..77f50d06ab 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs @@ -12,13 +12,10 @@ internal static void AccessWindowsAppSDK() string versionTag = global::Microsoft.WindowsAppSDK.Release.VersionTag; var minVersion = new PackageVersion(global::Microsoft.WindowsAppSDK.Runtime.Version.UInt64); var options = Options; - try + int hresult = 0; + if (!global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.TryInitialize(majorMinorVersion, versionTag, minVersion, options, out hresult)) { - global::Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap.Initialize(majorMinorVersion, versionTag, minVersion, options); - } - catch (global::System.Exception e) - { - global::System.Environment.FailFast(e.Message); + global::System.Environment.Exit(hr); } } From 285e3cdbc0c3411760d216d25add4bff7e0e4454 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 31 Mar 2022 12:41:07 -0700 Subject: [PATCH 12/16] Incorporated feedbacck --- ...crosoft.WindowsAppSDK.Bootstrap.CS.targets | 22 +++++++++---------- ...ndowsAppSDK-Nuget-Native.Bootstrap.targets | 8 +++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets index 338fa3cc2d..dab2da8673 100644 --- a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets +++ b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets @@ -1,23 +1,23 @@ - - true + + true - + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP + Condition="'$(WindowsAppSDKBootstrapInitialize)'=='true'"> diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets index 57bc9b0bf7..d77a0531b1 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets @@ -1,17 +1,17 @@ - - true + + true + Condition="'$(WindowsAppSDKBootstrapInitialize)'=='true'"> NotUsing MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT;%(PreprocessorDefinitions) - MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT;%(PreprocessorDefinitions) + MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE;%(PreprocessorDefinitions) MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK;%(PreprocessorDefinitions) MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED;%(PreprocessorDefinitions) MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST;%(PreprocessorDefinitions) From 53f3eb9eff05872eed7eefce101bb5d3c20c4993 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 31 Mar 2022 12:51:32 -0700 Subject: [PATCH 13/16] Incorproated feedback. Removed some stale comments --- .../MddBootstrap.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index b5bfa769bc..6f68ca591c 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -64,7 +64,7 @@ HRESULT MddBootstrapInitialize_Log( UINT32 majorMinorVersion, PCWSTR versionTag, PACKAGE_VERSION minVersion) noexcept; -HRESULT MddBootstrapInitialize_ShowUI( +HRESULT MddBootstrapInitialize_ShowUI_OnNoMatch( UINT32 majorMinorVersion, PCWSTR versionTag, PACKAGE_VERSION minVersion); @@ -127,10 +127,13 @@ STDAPI MddBootstrapInitialize2( DebugBreak(); } - if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnNoMatch_ShowUI) || - IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_SHOWUI")) + if (hr == HRESULT_FROM_WIN32(ERROR_NO_MATCH)) { - LOG_IF_FAILED(MddBootstrapInitialize_ShowUI(majorMinorVersion, versionTag, minVersion)); + if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnNoMatch_ShowUI) || + IsOptionEnabled(L"MICROSOFT_WINDOWSAPPRUNTIME_BOOTSTRAP_INITIALIZE_SHOWUI")) + { + LOG_IF_FAILED(MddBootstrapInitialize_ShowUI_OnNoMatch(majorMinorVersion, versionTag, minVersion)); + } } if (WI_IsFlagSet(options, MddBootstrapInitializeOptions_OnError_FailFast) || @@ -938,13 +941,11 @@ HRESULT MddBootstrapInitialize_Log( } CATCH_RETURN() -HRESULT MddBootstrapInitialize_ShowUI( +HRESULT MddBootstrapInitialize_ShowUI_OnNoMatch( UINT32 majorMinorVersion, PCWSTR versionTag, PACKAGE_VERSION minVersion) { - //TODO: Show this if ERROR_NO_MATCH vs simpler MessageBox("ERROR 0xN in Bootstrapper initialize", MB_OK) ? - // Get the message caption PCWSTR caption{}; wil::unique_cotaskmem_string captionString; @@ -1008,7 +1009,6 @@ HRESULT MddBootstrapInitialize_ShowUI( sei.cbSize = sizeof(sei); sei.lpVerb = L"open"; sei.lpFile = L"https://docs.microsoft.com/windows/apps/windows-app-sdk/downloads"; - //TODO:Replace with https://aka.ms/windowsappsdk/./latest/windowsappruntimeinstall-.exe sei.nShow = SW_SHOWNORMAL; LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&sei)); } From fa7f5f94883a43ce5a5ab6fea1d59550f178e8bb Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 31 Mar 2022 13:38:25 -0700 Subject: [PATCH 14/16] Removed unnecessary extra checks for WindowsAppSDKBootstrapInitialize --- .../Microsoft.WindowsAppSDK.Bootstrap.CS.targets | 10 ++-------- .../WindowsAppSDK-Nuget-Native.Bootstrap.targets | 8 +------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets index dab2da8673..40245ac05a 100644 --- a/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets +++ b/build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets @@ -1,10 +1,6 @@ - - true - - - + $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE @@ -15,9 +11,7 @@ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP - + diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets index d77a0531b1..573c99e2b1 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets @@ -1,12 +1,6 @@ - - true - - - + NotUsing From 91804c141c1ec18f8e39608f74d7c6184955e526 Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 31 Mar 2022 13:40:46 -0700 Subject: [PATCH 15/16] Renamed Microsoft.WindowsAppSDK.MddCommon.targets to Microsoft.WindowsAppSDK.BootstrapCommon.targets. Mdd==DynamicDependencies, which is a generic facility for any packcage. Bootstrap==specialization of DynamicDependencies, uniquely for WindowsAppSDK's runtime --- ....targets => Microsoft.WindowsAppSDK.BootstrapCommon.targets} | 0 build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets | 2 +- build/NuSpecs/WindowsAppSDK-Nuget-Native.targets | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename build/NuSpecs/{Microsoft.WindowsAppSDK.MddCommon.targets => Microsoft.WindowsAppSDK.BootstrapCommon.targets} (100%) diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.MddCommon.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.BootstrapCommon.targets similarity index 100% rename from build/NuSpecs/Microsoft.WindowsAppSDK.MddCommon.targets rename to build/NuSpecs/Microsoft.WindowsAppSDK.BootstrapCommon.targets diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets index 5db18898aa..6208013d3f 100644 --- a/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets +++ b/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets @@ -2,6 +2,6 @@ - + diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets index 36c4b27764..53ca33980f 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets @@ -61,7 +61,7 @@ - + From 117a462e9f3a02d05d6c607f867eb8e3e607a9ed Mon Sep 17 00:00:00 2001 From: Howard Kapustein Date: Thu, 31 Mar 2022 18:51:33 -0700 Subject: [PATCH 16/16] Updated reference to MddCommon --- .../WindowsAppSDK-CreateNugetPackage-Job.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-CreateNugetPackage-Job.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-CreateNugetPackage-Job.yml index a0f273469c..1296147305 100644 --- a/build/AzurePipelinesTemplates/WindowsAppSDK-CreateNugetPackage-Job.yml +++ b/build/AzurePipelinesTemplates/WindowsAppSDK-CreateNugetPackage-Job.yml @@ -62,7 +62,7 @@ jobs: Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.Foundation.props" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.Foundation.props" Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.Bootstrap.CS.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.Bootstrap.CS.targets" Copy-Item -Path "$targetsFilePath\WindowsAppSDK-Nuget-Native.Bootstrap.targets" -Destination "$fullpackagePath\build\native\WindowsAppSDK-Nuget-Native.Bootstrap.targets" - Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.MddCommon.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.MddCommon.targets" + Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.BootstrapCommon.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.BootstrapCommon.targets" Copy-Item -Path "$targetsFilePath\AppxManifest.xml" -Destination "$fullpackagePath\AppxManifest.xml" $manifestPath = $fullpackagePath+'\manifests'; @@ -70,7 +70,7 @@ jobs: $xslt = New-Object System.Xml.Xsl.XslCompiledTransform; $xslt.Load('build\TransformAppxManifest.xslt'); $xslt.Transform($fullpackagePath+'\AppxManifest.xml', $manifestPath+'\Microsoft.WindowsAppSdk.Foundation.manifest'); - + # - script: | # dir /s $(Build.SourcesDirectory)