diff --git a/dev/AppLifecycle/AppLifecycle.idl b/dev/AppLifecycle/AppLifecycle.idl index a6276c908a..6fdc5c60d2 100644 --- a/dev/AppLifecycle/AppLifecycle.idl +++ b/dev/AppLifecycle/AppLifecycle.idl @@ -3,6 +3,10 @@ namespace Microsoft.Windows.AppLifecycle { + [contractversion(2)] + apicontract AppLifecycleContract {}; + + [contract(AppLifecycleContract, 1)] enum ExtendedActivationKind { Launch = 0, @@ -53,20 +57,26 @@ namespace Microsoft.Windows.AppLifecycle // Windows.ApplicationModel.Activation.ActivationKind. Push = 5000, + + [contract(AppLifecycleContract, 2)] AppNotification, }; + [contract(AppLifecycleContract, 1)] runtimeclass AppActivationArguments { ExtendedActivationKind Kind { get; }; IInspectable Data{ get; }; }; + [contract(AppLifecycleContract, 1)] runtimeclass AppInstance { static AppInstance GetCurrent(); static Windows.Foundation.Collections.IVector GetInstances(); static AppInstance FindOrRegisterForKey(String key); + + [contract(AppLifecycleContract, 2)] static Windows.ApplicationModel.Core.AppRestartFailureReason Restart(String arguments); void UnregisterKey(); @@ -79,6 +89,7 @@ namespace Microsoft.Windows.AppLifecycle UInt32 ProcessId{ get; }; } + [contract(AppLifecycleContract, 1)] static runtimeclass ActivationRegistrationManager { static void RegisterForFileTypeActivation(String[] supportedFileTypes, String logo, diff --git a/dev/AppNotifications/AppNotification.cpp b/dev/AppNotifications/AppNotification.cpp index 0ab6b00316..ed30b7946c 100644 --- a/dev/AppNotifications/AppNotification.cpp +++ b/dev/AppNotifications/AppNotification.cpp @@ -1,7 +1,6 @@ #include "pch.h" #include "AppNotification.h" #include "Microsoft.Windows.AppNotifications.AppNotification.g.cpp" -#include using namespace winrt::Windows::Data::Xml::Dom; @@ -9,8 +8,6 @@ namespace winrt::Microsoft::Windows::AppNotifications::implementation { AppNotification::AppNotification(hstring const& payload) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::AppNotifications::Feature_AppNotifications::IsEnabled()); - XmlDocument xmlDocument{}; // We call LoadXml to verify the payload is xml diff --git a/dev/AppNotifications/AppNotificationManager.cpp b/dev/AppNotifications/AppNotificationManager.cpp index a30ffa8550..c5099d0b3d 100644 --- a/dev/AppNotifications/AppNotificationManager.cpp +++ b/dev/AppNotifications/AppNotificationManager.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include using namespace std::literals; diff --git a/dev/AppNotifications/AppNotificationProgressData.cpp b/dev/AppNotifications/AppNotificationProgressData.cpp index e7f48fbd40..9f4371be97 100644 --- a/dev/AppNotifications/AppNotificationProgressData.cpp +++ b/dev/AppNotifications/AppNotificationProgressData.cpp @@ -1,14 +1,11 @@ #include "pch.h" #include "AppNotificationProgressData.h" #include "Microsoft.Windows.AppNotifications.AppNotificationProgressData.g.cpp" -#include namespace winrt::Microsoft::Windows::AppNotifications::implementation { AppNotificationProgressData::AppNotificationProgressData(uint32_t sequenceNumber) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::AppNotifications::Feature_AppNotifications::IsEnabled()); - THROW_HR_IF(E_INVALIDARG, sequenceNumber == 0); // The sequence number is always greater than 0 m_sequenceNumber = sequenceNumber; } diff --git a/dev/AppNotifications/AppNotifications.idl b/dev/AppNotifications/AppNotifications.idl index 73381073af..023952951a 100644 --- a/dev/AppNotifications/AppNotifications.idl +++ b/dev/AppNotifications/AppNotifications.idl @@ -1,17 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#include - import "..\AppLifecycle\AppLifecycle.idl"; namespace Microsoft.Windows.AppNotifications { - [contractversion(1)] apicontract WindowsAppNotificationsContract {} // Event args for the Notification Activation - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] runtimeclass AppNotificationActivatedEventArgs { @@ -23,7 +19,6 @@ namespace Microsoft.Windows.AppNotifications } // Notification Progress Data - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] runtimeclass AppNotificationProgressData { @@ -49,7 +44,6 @@ namespace Microsoft.Windows.AppNotifications } // The Notification User Setting or Notification Group Policy Setting - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] enum AppNotificationSetting { @@ -61,7 +55,6 @@ namespace Microsoft.Windows.AppNotifications }; // The Result for a Notification Progress related operation - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] enum AppNotificationProgressResult { @@ -70,7 +63,6 @@ namespace Microsoft.Windows.AppNotifications }; // The Priority of the Notification UI associated with it's popup in the Action Centre - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] enum AppNotificationPriority { @@ -78,7 +70,6 @@ namespace Microsoft.Windows.AppNotifications High, // The notification should be treated as high priority. For desktop PCs, this means during connected standby mode the incoming notification can turn on the screen for Surface-like devices if it doesn't have a closed lid detected. }; - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] runtimeclass AppNotification { @@ -115,7 +106,6 @@ namespace Microsoft.Windows.AppNotifications } // The manager class which encompasses all App Notification API Functionality - [feature(Feature_AppNotifications)] [contract(WindowsAppNotificationsContract, 1)] runtimeclass AppNotificationManager { diff --git a/dev/DynamicDependency/API/MsixDynamicDependency.h b/dev/DynamicDependency/API/MsixDynamicDependency.h index 47c5ceff1e..53c67e482c 100644 --- a/dev/DynamicDependency/API/MsixDynamicDependency.h +++ b/dev/DynamicDependency/API/MsixDynamicDependency.h @@ -23,6 +23,9 @@ /// MSIX Dynamic Dependency: Bootstrap initialization found an applicable DynamicDependencyLifetimeManager (DDLM) best matching the criteria #define MDD_E_BOOTSTRAP_INITIALIZE_DDLM_FOUND _HRESULT_TYPEDEF_(0x80040013L) +/// MSIX Dynamic Dependency: Bootstrap initialization request is incompatible with current Bootstrap initialization state. +#define MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE _HRESULT_TYPEDEF_(0x80040014L) + enum class MddCreatePackageDependencyOptions : uint32_t { None = 0, diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 6d7aa507fe..17e2b8d6e1 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -24,8 +24,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { PushNotificationChannel::PushNotificationChannel(struct ChannelDetails channelInfo) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); - std::swap(m_channelInfo, channelInfo); } diff --git a/dev/PushNotifications/PushNotificationChannel.h b/dev/PushNotifications/PushNotificationChannel.h index 92b9b148df..bc7a78dd74 100644 --- a/dev/PushNotifications/PushNotificationChannel.h +++ b/dev/PushNotifications/PushNotificationChannel.h @@ -3,9 +3,7 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.h" - #include "winrt/Windows.Networking.PushNotifications.h" -#include #include "externs.h" namespace winrt::Microsoft::Windows::PushNotifications::implementation diff --git a/dev/PushNotifications/PushNotificationCreateChannelResult.cpp b/dev/PushNotifications/PushNotificationCreateChannelResult.cpp index 7774e8b3ab..c8d2db6ab8 100644 --- a/dev/PushNotifications/PushNotificationCreateChannelResult.cpp +++ b/dev/PushNotifications/PushNotificationCreateChannelResult.cpp @@ -3,7 +3,6 @@ #include "pch.h" #include "PushNotificationCreateChannelResult.h" -#include #include "Microsoft.Windows.PushNotifications.PushNotificationCreateChannelResult.g.cpp" namespace winrt::Microsoft::Windows::PushNotifications::implementation @@ -13,7 +12,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_extendedError(extendedError), m_status(status) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } PushNotificationChannel PushNotificationCreateChannelResult::Channel() diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 5d2a08547e..2f7856bac5 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -137,8 +137,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::Microsoft::Windows::PushNotifications::PushNotificationManager PushNotificationManager::Default() { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); - static wil::srwlock lock; auto criticalSection{ lock.lock_exclusive() }; @@ -196,8 +194,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::IAsyncOperationWithProgress PushNotificationManager::CreateChannelAsync(const winrt::guid remoteId) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); - if (!IsSupported()) { co_return winrt::make( diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp index 5b3b8589f7..4370672555 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include "PushNotificationReceivedEventArgs.h" #include "Microsoft.Windows.PushNotifications.PushNotificationReceivedEventArgs.g.cpp" #include @@ -31,28 +30,24 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_rawNotificationPayload(BuildPayload(backgroundTask.TriggerDetails().as().ContentBytes())), m_unpackagedAppScenario(false) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::PushNotificationReceivedEventArgs const& args): m_rawNotificationPayload(BuildPayload(args.RawNotification().ContentBytes())), m_unpackagedAppScenario(false) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(byte* const& payload, ULONG const& length) : m_rawNotificationPayload(BuildPayload(payload, length)), m_unpackagedAppScenario(true) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::hstring const& payload) : m_rawNotificationPayload(BuildPayload(payload)), m_unpackagedAppScenario(true) { - THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); } std::vector PushNotificationReceivedEventArgs::BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer) diff --git a/dev/PushNotifications/PushNotifications.idl b/dev/PushNotifications/PushNotifications.idl index aff6197164..b77ab0d922 100644 --- a/dev/PushNotifications/PushNotifications.idl +++ b/dev/PushNotifications/PushNotifications.idl @@ -1,12 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#include - namespace Microsoft.Windows.PushNotifications { - [feature(Feature_PushNotifications)] + [contractversion(1)] + apicontract PushNotificationsContract {} + // Event args for the Push payload. + [contract(PushNotificationsContract, 1)] runtimeclass PushNotificationReceivedEventArgs { // The Push payload @@ -19,7 +20,7 @@ namespace Microsoft.Windows.PushNotifications event Windows.ApplicationModel.Background.BackgroundTaskCanceledEventHandler Canceled; }; - [feature(Feature_PushNotifications)] + [contract(PushNotificationsContract, 1)] enum PushNotificationChannelStatus { InProgress, // The request is in progress and there is no retry operation @@ -29,7 +30,7 @@ namespace Microsoft.Windows.PushNotifications }; // The PushNotificationChannel Progress result - [feature(Feature_PushNotifications)] + [contract(PushNotificationsContract, 1)] struct PushNotificationCreateChannelStatus { // Either InProgress or InProgressRetry status @@ -42,7 +43,7 @@ namespace Microsoft.Windows.PushNotifications UInt32 retryCount; }; - [feature(Feature_PushNotifications)] + [contract(PushNotificationsContract, 1)] runtimeclass PushNotificationChannel { // The Channel Uri for app to Post a notification to. @@ -55,7 +56,7 @@ namespace Microsoft.Windows.PushNotifications void Close(); } - [feature(Feature_PushNotifications)] + [contract(PushNotificationsContract, 1)] runtimeclass PushNotificationCreateChannelResult { // The Push channel associated with the Result. Valid only if status is CompletedSuccess. @@ -68,7 +69,7 @@ namespace Microsoft.Windows.PushNotifications PushNotificationChannelStatus Status { get; }; }; - [feature(Feature_PushNotifications)] + [contract(PushNotificationsContract, 1)] runtimeclass PushNotificationManager { // Checks to see if the APIs are supported for the Desktop app diff --git a/dev/VSIX/ItemTemplates/Desktop/CSharp/BlankWindow/WinUI.Desktop.Cs.BlankWindow.vstemplate b/dev/VSIX/ItemTemplates/Desktop/CSharp/BlankWindow/WinUI.Desktop.Cs.BlankWindow.vstemplate index 0b99a2dc00..82fa0234d5 100644 --- a/dev/VSIX/ItemTemplates/Desktop/CSharp/BlankWindow/WinUI.Desktop.Cs.BlankWindow.vstemplate +++ b/dev/VSIX/ItemTemplates/Desktop/CSharp/BlankWindow/WinUI.Desktop.Cs.BlankWindow.vstemplate @@ -10,7 +10,7 @@ WinRT-Managed-UAP CSharp + SharedAssetsProject 2 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Desktop/CppWinRT/BlankWindow/WinUI.Desktop.CppWinRT.BlankWindow.vstemplate b/dev/VSIX/ItemTemplates/Desktop/CppWinRT/BlankWindow/WinUI.Desktop.CppWinRT.BlankWindow.vstemplate index abcfffdb20..b3a33ad006 100644 --- a/dev/VSIX/ItemTemplates/Desktop/CppWinRT/BlankWindow/WinUI.Desktop.CppWinRT.BlankWindow.vstemplate +++ b/dev/VSIX/ItemTemplates/Desktop/CppWinRT/BlankWindow/WinUI.Desktop.CppWinRT.BlankWindow.vstemplate @@ -8,7 +8,7 @@ VC WinUI.Desktop.CppWinRT.BlankWindow 2 - true + false Windows blend cpp diff --git a/dev/VSIX/ItemTemplates/Neutral/CSharp/BlankPage/WinUI.Neutral.Cs.BlankPage.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CSharp/BlankPage/WinUI.Neutral.Cs.BlankPage.vstemplate index 01392a407b..8c26f7639d 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CSharp/BlankPage/WinUI.Neutral.Cs.BlankPage.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CSharp/BlankPage/WinUI.Neutral.Cs.BlankPage.vstemplate @@ -10,7 +10,7 @@ WinRT-Managed-UAP CSharp + SharedAssetsProject 2 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Neutral/CSharp/ResourceDictionary/WinUI.Neutral.Cs.ResourceDictionary.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CSharp/ResourceDictionary/WinUI.Neutral.Cs.ResourceDictionary.vstemplate index 74c46d807f..aee9c7f3bf 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CSharp/ResourceDictionary/WinUI.Neutral.Cs.ResourceDictionary.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CSharp/ResourceDictionary/WinUI.Neutral.Cs.ResourceDictionary.vstemplate @@ -10,7 +10,7 @@ WinRT-Managed-UAP CSharp + SharedAssetsProject 1 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Neutral/CSharp/Resw/WinUI.Neutral.Cs.Resw.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CSharp/Resw/WinUI.Neutral.Cs.Resw.vstemplate index bd128dc43e..a526c2e10f 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CSharp/Resw/WinUI.Neutral.Cs.Resw.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CSharp/Resw/WinUI.Neutral.Cs.Resw.vstemplate @@ -8,7 +8,7 @@ CSharp WinUI.Cs.Neutral.Resw 1 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Neutral/CSharp/TemplatedControl/WinUI.Neutral.Cs.TemplatedControl.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CSharp/TemplatedControl/WinUI.Neutral.Cs.TemplatedControl.vstemplate index e483063e5a..727685368f 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CSharp/TemplatedControl/WinUI.Neutral.Cs.TemplatedControl.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CSharp/TemplatedControl/WinUI.Neutral.Cs.TemplatedControl.vstemplate @@ -10,7 +10,7 @@ WinRT-Managed-UAP CSharp + SharedAssetsProject 2 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Neutral/CSharp/UserControl/WinUI.Neutral.Cs.UserControl.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CSharp/UserControl/WinUI.Neutral.Cs.UserControl.vstemplate index cf6070b6e1..f86e05835a 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CSharp/UserControl/WinUI.Neutral.Cs.UserControl.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CSharp/UserControl/WinUI.Neutral.Cs.UserControl.vstemplate @@ -10,7 +10,7 @@ WinRT-Managed-UAP CSharp + SharedAssetsProject 2 - true + false Windows blend csharp diff --git a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/BlankPage/WinUI.Neutral.CppWinRT.BlankPage.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/BlankPage/WinUI.Neutral.CppWinRT.BlankPage.vstemplate index 2affb81158..92bf1226be 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/BlankPage/WinUI.Neutral.CppWinRT.BlankPage.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/BlankPage/WinUI.Neutral.CppWinRT.BlankPage.vstemplate @@ -8,7 +8,7 @@ VC WinUI.Neutral.CppWinRT.BlankPage 2 - true + false Windows blend cpp diff --git a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/ResourceDictionary/WinUI.Neutral.CppWinRT.ResourceDictionary.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/ResourceDictionary/WinUI.Neutral.CppWinRT.ResourceDictionary.vstemplate index f773bd8a11..01de7c4cb1 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/ResourceDictionary/WinUI.Neutral.CppWinRT.ResourceDictionary.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/ResourceDictionary/WinUI.Neutral.CppWinRT.ResourceDictionary.vstemplate @@ -8,7 +8,7 @@ VC WinUI.Neutral.CppWinRT.ResourceDictionary 1 - true + false Windows blend cpp diff --git a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/Resw/WinUI.Neutral.CppWinRT.Resw.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/Resw/WinUI.Neutral.CppWinRT.Resw.vstemplate index 1e8d36574c..74973e6fe3 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/Resw/WinUI.Neutral.CppWinRT.Resw.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/Resw/WinUI.Neutral.CppWinRT.Resw.vstemplate @@ -8,7 +8,7 @@ VC WinUI.CppWinRT.Neutral.Resw 1 - true + false Windows blend cpp diff --git a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/TemplatedControl/WinUI.Neutral.CppWinRT.TemplatedControl.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/TemplatedControl/WinUI.Neutral.CppWinRT.TemplatedControl.vstemplate index 9836bce47a..902d8e40a5 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/TemplatedControl/WinUI.Neutral.CppWinRT.TemplatedControl.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/TemplatedControl/WinUI.Neutral.CppWinRT.TemplatedControl.vstemplate @@ -8,7 +8,7 @@ VC WinUI.Neutral.CppWinRT.TemplatedControl 2 - true + false Windows blend cpp diff --git a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/UserControl/WinUI.Neutral.CppWinRT.UserControl.vstemplate b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/UserControl/WinUI.Neutral.CppWinRT.UserControl.vstemplate index f5181d14c8..39b7e47be1 100644 --- a/dev/VSIX/ItemTemplates/Neutral/CppWinRT/UserControl/WinUI.Neutral.CppWinRT.UserControl.vstemplate +++ b/dev/VSIX/ItemTemplates/Neutral/CppWinRT/UserControl/WinUI.Neutral.CppWinRT.UserControl.vstemplate @@ -8,7 +8,7 @@ VC WinUI.Neutral.CppWinRT.UserControl 2 - true + false Windows blend cpp diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp index 4992086f8d..fca34d048f 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.cpp @@ -12,6 +12,14 @@ #include +void VerifyInitializationIsCompatible( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion); +void FirstTimeInitialization( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion); wil::unique_cotaskmem_ptr GetFrameworkPackageInfoForPackage(PCWSTR packageFullName, const PACKAGE_INFO*& frameworkPackageInfo); DLL_DIRECTORY_COOKIE AddFrameworkToPath(PCWSTR path); void RemoveFrameworkFromPath(PCWSTR frameworkPath); @@ -47,11 +55,18 @@ void FindDDLMViaEnumeration( std::wstring& ddlmPackageFullName); CLSID GetClsid(const winrt::Windows::ApplicationModel::AppExtensions::AppExtension& appExtension); -IDynamicDependencyLifetimeManager* g_lifetimeManager{}; -wil::unique_event g_endTheLifetimeManagerEvent; -wil::unique_hmodule g_windowsAppRuntimeDll; -wil::unique_process_heap_string g_packageDependencyId; -MDD_PACKAGEDEPENDENCY_CONTEXT g_packageDependencyContext{}; +static std::mutex g_initializationLock; +static std::atomic g_initializationCount{}; + +static IDynamicDependencyLifetimeManager* g_lifetimeManager{}; +static wil::unique_event g_endTheLifetimeManagerEvent; +static wil::unique_hmodule g_windowsAppRuntimeDll; +static wil::unique_process_heap_string g_packageDependencyId; +static MDD_PACKAGEDEPENDENCY_CONTEXT g_packageDependencyContext{}; + +static UINT32 g_initializationMajorMinorVersion{}; +static std::wstring g_initializationVersionTag; +static PACKAGE_VERSION g_initializationFrameworkPackageVersion{}; static std::wstring g_test_ddlmPackageNamePrefix; static std::wstring g_test_ddlmPackagePublisherId; @@ -64,55 +79,42 @@ STDAPI MddBootstrapInitialize( // Dynamic Dependencies Bootstrap API requires a non-packaged process LOG_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), AppModel::Identity::IsPackagedProcess()); - FAIL_FAST_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), g_lifetimeManager != nullptr); - FAIL_FAST_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), g_windowsAppRuntimeDll != nullptr); - FAIL_FAST_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), g_packageDependencyId != nullptr); - FAIL_FAST_HR_IF(HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), g_packageDependencyContext != nullptr); - - wil::unique_cotaskmem_string packageFullName; - wil::com_ptr_nothrow lifetimeManager; - wil::unique_event endTheLifetimeManagerEvent; - CreateLifetimeManager(majorMinorVersion, versionTag, minVersion, lifetimeManager, endTheLifetimeManagerEvent, packageFullName); - - const PACKAGE_INFO* frameworkPackageInfo{}; - auto packageInfoBuffer{ GetFrameworkPackageInfoForPackage(packageFullName.get(), frameworkPackageInfo) }; - - // Temporarily add the framework's package directory to PATH so LoadLibrary can find it and any colocated imports - wil::unique_dll_directory_cookie dllDirectoryCookie{ AddFrameworkToPath(frameworkPackageInfo->path) }; - - auto windowsAppRuntimeDllFilename{ std::wstring(frameworkPackageInfo->path) + L"\\Microsoft.WindowsAppRuntime.dll" }; - wil::unique_hmodule windowsAppRuntimeDll(LoadLibraryEx(windowsAppRuntimeDllFilename.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH)); - if (!windowsAppRuntimeDll) + // Are we already initialized? + auto lock{ std::lock_guard(g_initializationLock) }; + if (g_initializationCount > 0) { - const auto lastError{ GetLastError() }; - THROW_WIN32_MSG(lastError, "Error in LoadLibrary: %d (0x%X) loading %ls", lastError, lastError, windowsAppRuntimeDllFilename.c_str()); + // Verify the request is compatible with our already initialized state + VerifyInitializationIsCompatible(majorMinorVersion, versionTag, minVersion); + } + else + { + // First to the key! Do the initialization + FirstTimeInitialization(majorMinorVersion, versionTag, minVersion); } - const MddPackageDependencyProcessorArchitectures architectureFilter{}; - const auto lifetimeKind{ MddPackageDependencyLifetimeKind::Process }; - const MddCreatePackageDependencyOptions createOptions{}; - wil::unique_process_heap_string packageDependencyId; - THROW_IF_FAILED(MddTryCreatePackageDependency(nullptr, frameworkPackageInfo->packageFamilyName, minVersion, architectureFilter, lifetimeKind, nullptr, createOptions, &packageDependencyId)); - // - const MddAddPackageDependencyOptions addOptions{}; - MDD_PACKAGEDEPENDENCY_CONTEXT packageDependencyContext{}; - THROW_IF_FAILED(MddAddPackageDependency(packageDependencyId.get(), MDD_PACKAGE_DEPENDENCY_RANK_DEFAULT, addOptions, &packageDependencyContext, nullptr)); - - // Remove out temporary path addition - RemoveFrameworkFromPath(frameworkPackageInfo->path); - dllDirectoryCookie.reset(); - - g_lifetimeManager = lifetimeManager.detach(); - g_endTheLifetimeManagerEvent = std::move(endTheLifetimeManagerEvent); - g_windowsAppRuntimeDll = std::move(windowsAppRuntimeDll); - g_packageDependencyId = std::move(packageDependencyId); - g_packageDependencyContext = packageDependencyContext; + // Success! + ++g_initializationCount; return S_OK; } CATCH_RETURN(); STDAPI_(void) MddBootstrapShutdown() noexcept { + auto lock{ std::lock_guard(g_initializationLock) }; + const auto initializationCount{ g_initializationCount.load() }; + if (initializationCount > 1) + { + // Multiply initialized. Just decrement our count + --g_initializationCount; + return; + } + else if (initializationCount == 0) + { + // Not initialized. Nothing to do + return; + } + + // Last one out turn out the lights... if (g_packageDependencyContext && g_windowsAppRuntimeDll) { MddRemovePackageDependency(g_packageDependencyContext); @@ -135,6 +137,12 @@ STDAPI_(void) MddBootstrapShutdown() noexcept g_lifetimeManager->Release(); g_lifetimeManager = nullptr; } + + g_initializationMajorMinorVersion = {}; + g_initializationVersionTag.clear(); + g_initializationFrameworkPackageVersion = {}; + + --g_initializationCount; } STDAPI MddBootstrapTestInitialize( @@ -151,6 +159,107 @@ STDAPI MddBootstrapTestInitialize( return S_OK; } CATCH_RETURN(); +void VerifyInitializationIsCompatible( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) +{ + // Sanity check we're already initialized + // g_lifetimeManager is optional. Don't check it + // g_endTheLifetimeManagerEvent is optional. Don't check it + FAIL_FAST_HR_IF(E_UNEXPECTED, g_windowsAppRuntimeDll == nullptr); + FAIL_FAST_HR_IF(E_UNEXPECTED, g_packageDependencyId == nullptr); + FAIL_FAST_HR_IF(E_UNEXPECTED, g_packageDependencyContext == nullptr); + + // Is the initialization request compatible with the current initialization state? + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + majorMinorVersion != g_initializationMajorMinorVersion, + "MddBootstrapInitialize(***0x%08X***, '%ls', %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + CompareStringOrdinal((!versionTag ? L"" : versionTag), -1, g_initializationVersionTag.c_str(), -1, TRUE) != CSTR_EQUAL, + "MddBootstrapInitialize(0x%08X, ***'%ls'***, %hu.%hu.%hu.%hu) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); + THROW_HR_IF_MSG(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, + minVersion.Version > g_initializationFrameworkPackageVersion.Version, + "MddBootstrapInitialize(0x%08X, '%ls', ***%hu.%hu.%hu.%hu***) not compatible with current initialization state (0x%X, '%ls', %hu.%hu.%hu.%hu)", + majorMinorVersion, (!versionTag ? L"" : versionTag), + minVersion.Major, minVersion.Minor, minVersion.Build, minVersion.Revision, + g_initializationMajorMinorVersion, g_initializationVersionTag.c_str(), + g_initializationFrameworkPackageVersion.Major, g_initializationFrameworkPackageVersion.Minor, + g_initializationFrameworkPackageVersion.Build, g_initializationFrameworkPackageVersion.Revision); +} + +void FirstTimeInitialization( + UINT32 majorMinorVersion, + PCWSTR versionTag, + PACKAGE_VERSION minVersion) +{ + // Sanity check we're not already initialized + // g_lifetimeManager is optional. Don't check it + // g_endTheLifetimeManagerEvent is optional. Don't check it + FAIL_FAST_HR_IF(E_UNEXPECTED, g_windowsAppRuntimeDll != nullptr); + FAIL_FAST_HR_IF(E_UNEXPECTED, g_packageDependencyId != nullptr); + FAIL_FAST_HR_IF(E_UNEXPECTED, g_packageDependencyContext != nullptr); + + // Make a copy of the versionTag in preparation of succcess + auto packageVersionTag{ std::wstring(!versionTag ? L"" : versionTag) }; + + // Create the lifetime manager + wil::unique_cotaskmem_string packageFullName; + wil::com_ptr_nothrow lifetimeManager; + wil::unique_event endTheLifetimeManagerEvent; + CreateLifetimeManager(majorMinorVersion, versionTag, minVersion, lifetimeManager, endTheLifetimeManagerEvent, packageFullName); + + const PACKAGE_INFO* frameworkPackageInfo{}; + auto packageInfoBuffer{ GetFrameworkPackageInfoForPackage(packageFullName.get(), frameworkPackageInfo) }; + + // Temporarily add the framework's package directory to PATH so LoadLibrary can find it and any colocated imports + wil::unique_dll_directory_cookie dllDirectoryCookie{ AddFrameworkToPath(frameworkPackageInfo->path) }; + + auto windowsAppRuntimeDllFilename{ std::wstring(frameworkPackageInfo->path) + L"\\Microsoft.WindowsAppRuntime.dll" }; + wil::unique_hmodule windowsAppRuntimeDll(LoadLibraryEx(windowsAppRuntimeDllFilename.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH)); + if (!windowsAppRuntimeDll) + { + const auto lastError{ GetLastError() }; + THROW_WIN32_MSG(lastError, "Error in LoadLibrary: %d (0x%X) loading %ls", lastError, lastError, windowsAppRuntimeDllFilename.c_str()); + } + + // Add the framework package to the package graph + const MddPackageDependencyProcessorArchitectures architectureFilter{}; + const auto lifetimeKind{ MddPackageDependencyLifetimeKind::Process }; + const MddCreatePackageDependencyOptions createOptions{}; + wil::unique_process_heap_string packageDependencyId; + THROW_IF_FAILED(MddTryCreatePackageDependency(nullptr, frameworkPackageInfo->packageFamilyName, minVersion, architectureFilter, lifetimeKind, nullptr, createOptions, &packageDependencyId)); + // + const MddAddPackageDependencyOptions addOptions{}; + MDD_PACKAGEDEPENDENCY_CONTEXT packageDependencyContext{}; + THROW_IF_FAILED(MddAddPackageDependency(packageDependencyId.get(), MDD_PACKAGE_DEPENDENCY_RANK_DEFAULT, addOptions, &packageDependencyContext, nullptr)); + + // Remove our temporary path addition + RemoveFrameworkFromPath(frameworkPackageInfo->path); + dllDirectoryCookie.reset(); + + // Track our initialized state + g_lifetimeManager = lifetimeManager.detach(); + g_endTheLifetimeManagerEvent = std::move(endTheLifetimeManagerEvent); + g_windowsAppRuntimeDll = std::move(windowsAppRuntimeDll); + g_packageDependencyId = std::move(packageDependencyId); + g_packageDependencyContext = packageDependencyContext; + // + g_initializationMajorMinorVersion = majorMinorVersion; + g_initializationVersionTag = std::move(packageVersionTag); + g_initializationFrameworkPackageVersion.Version = frameworkPackageInfo->packageId.version.Version; +} + /// Determine the path for the Windows App Runtime Framework package wil::unique_cotaskmem_ptr GetFrameworkPackageInfoForPackage(PCWSTR packageFullName, const PACKAGE_INFO*& frameworkPackageInfo) { diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h index 09b7ed8af3..ee7f38b461 100644 --- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h +++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrap.h @@ -12,6 +12,11 @@ /// 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 diff --git a/specs/dynamicdependencies/DynamicDependencies.md b/specs/dynamicdependencies/DynamicDependencies.md index 55e2e00bc8..255d928da7 100644 --- a/specs/dynamicdependencies/DynamicDependencies.md +++ b/specs/dynamicdependencies/DynamicDependencies.md @@ -1268,6 +1268,11 @@ This header contains the Bootstrap API /// 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 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. "prerelease". /// @param minVersion the minimum version to use @@ -1322,6 +1327,11 @@ namespace DynamicDependency::Bootstrap /// 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. + /// /// @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 @@ -1342,6 +1352,11 @@ namespace DynamicDependency::Bootstrap /// 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 exception is thrown. + /// /// @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 @@ -1362,6 +1377,11 @@ namespace DynamicDependency::Bootstrap /// 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 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 diff --git a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp index 5e66236787..5f5f9277db 100644 --- a/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp +++ b/test/DynamicDependency/Test_Win32/TestMddBootstrap.cpp @@ -77,8 +77,8 @@ 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 minVersion{}; - VERIFY_SUCCEEDED(MddBootstrapInitialize(c_Version_MajorMinor, nullptr, minVersion)); + const PACKAGE_VERSION c_minVersion{}; + VERIFY_SUCCEEDED(MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); MddBootstrapShutdown(); } @@ -129,12 +129,93 @@ 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 minVersion{}; - VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, minVersion)); + const PACKAGE_VERSION c_minVersion{}; + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); MddBootstrapShutdown(); } + TEST_METHOD(Initialize2x) + { + 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(S_OK, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); + + MddBootstrapShutdown(); + MddBootstrapShutdown(); + } + + TEST_METHOD(Initialize2xIncompatible) + { + 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(S_OK, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion)); + + const UINT32 c_Version_MajorMinor_Incompatible{ c_Version_MajorMinor + 1 }; + VERIFY_ARE_EQUAL(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, MddBootstrapInitialize(c_Version_MajorMinor_Incompatible, nullptr, c_minVersion)); + + VERIFY_ARE_EQUAL(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, MddBootstrapInitialize(c_Version_MajorMinor, L"NotTheVersionTag", c_minVersion)); + + const PACKAGE_VERSION c_minVersion_Incompatible{ UINT64_MAX }; + VERIFY_ARE_EQUAL(MDD_E_BOOTSTRAP_INITIALIZE_INCOMPATIBLE, MddBootstrapInitialize(c_Version_MajorMinor, nullptr, c_minVersion_Incompatible)); + + MddBootstrapShutdown(); + } + + TEST_METHOD(InitializeShutdownMultiple) + { + 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_MajorMinor1{ Test::Packages::WindowsAppRuntimeFramework::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion1{}; + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize(c_Version_MajorMinor1, nullptr, c_minVersion1)); + MddBootstrapShutdown(); + + // Same criteria but MinVersion=package version. Verify Initialize+Shutdown brings us back + // to initial state so we can initialize again with different (but successful) criteria + const UINT32 c_Version_MajorMinor2{ Test::Packages::WindowsAppRuntimeFramework::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion2{ Test::Packages::WindowsAppRuntimeFramework::GetPackageVersion() }; + VERIFY_ARE_NOT_EQUAL(c_minVersion2.Version, c_minVersion1.Version); + VERIFY_ARE_EQUAL(S_OK, MddBootstrapInitialize(c_Version_MajorMinor2, nullptr, c_minVersion2)); + MddBootstrapShutdown(); + + // Incompatible criteria. Verify Initialize+Shutdown brought us + // back to initial state so we can fail to initialize as expected + const UINT32 c_Version_MajorMinor3{ Test::Packages::WindowsAppRuntimeFramework::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion3{}; + VERIFY_ARE_EQUAL(c_minVersion3.Version, c_minVersion1.Version); + VERIFY_ARE_NOT_EQUAL(c_minVersion3.Version, c_minVersion2.Version); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NO_MATCH), MddBootstrapInitialize(c_Version_MajorMinor3, L"NotTheVersionTag", c_minVersion3)); + + // Incompatible criteria. Verify Initialize+Shutdown brought us + // back to initial state so we can fail to initialize as expected + const UINT32 c_Version_MajorMinor4{ Test::Packages::WindowsAppRuntimeFramework::c_Version_MajorMinor }; + const PACKAGE_VERSION c_minVersion4{ Test::Packages::WindowsAppRuntimeFramework::GetPackageVersion().Version + 1 }; + VERIFY_ARE_NOT_EQUAL(c_minVersion4.Version, c_minVersion1.Version); + VERIFY_ARE_NOT_EQUAL(c_minVersion4.Version, c_minVersion2.Version); + VERIFY_ARE_NOT_EQUAL(c_minVersion4.Version, c_minVersion3.Version); + VERIFY_ARE_EQUAL(HRESULT_FROM_WIN32(ERROR_NO_MATCH), MddBootstrapInitialize(c_Version_MajorMinor4, nullptr, c_minVersion4)); + + // Same criteria but MinVersion((GetPackageVersion().Major << 16) | GetPackageVersion().Minor); + } + constexpr const UINT32 c_Version_MajorMinor = GetPackageVersionMajorMinor(); } namespace Test::Packages::DynamicDependencyDataStore