From 52571ee50e8eaf160d1a9aeda144cecf1eff9e5d Mon Sep 17 00:00:00 2001 From: Jevan Saks Date: Mon, 16 Dec 2019 09:31:13 -0800 Subject: [PATCH] Fix IsInFrameworkPackage logic (#1762) --- dev/dll/MUXControlsFactory.cpp | 8 -------- dev/dll/SharedHelpers.cpp | 13 +++++++------ dev/dll/dllmain.cpp | 14 ++++++++++++++ idl/Microsoft.UI.Xaml.idl | 14 -------------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/dev/dll/MUXControlsFactory.cpp b/dev/dll/MUXControlsFactory.cpp index 635cccc422..d43aba22f5 100644 --- a/dev/dll/MUXControlsFactory.cpp +++ b/dev/dll/MUXControlsFactory.cpp @@ -12,14 +12,6 @@ #include "XamlControlsXamlMetaDataProvider.g.cpp" -namespace winrt::Microsoft::UI::Private::Controls -{ - namespace factory_implementation { using FrameworkPackageDetector = MUXControlsFactory; } - namespace implementation { using FrameworkPackageDetector = XamlMetadataProvider; } -} -#include "FrameworkPackageDetector.g.cpp" - - bool MUXControlsFactory::s_initialized{ false }; void MUXControlsFactory::EnsureInitialized() diff --git a/dev/dll/SharedHelpers.cpp b/dev/dll/SharedHelpers.cpp index 8fff319a64..8e4516e083 100644 --- a/dev/dll/SharedHelpers.cpp +++ b/dev/dll/SharedHelpers.cpp @@ -263,13 +263,14 @@ bool SharedHelpers::IsInFrameworkPackage() static bool isInFrameworkPackage = []() { // Special type that we manually list here which is not part of the Nuget dll distribution package. // This is our breadcrumb that we leave to be able to detect at runtime that we're using the framework package. - // It's listed only in AppxManifest.xml as an activatable type but it isn't activatable.; - // NOTE: calling the "internal" winrt_get_activation_factory in module.g.cpp so we don't raise an exception when - // this fails in prerelease builds. - + // It's listed only in the Framework packages' AppxManifest.xml as an activatable type but only so + // that RoGetActivationFactory will change behavior and call our DllGetActivationFactory. It doesn't + // mater what comes back for the activationfactory. If it succeeds it means we're running against + // the framework package. + + winrt::hstring typeName{ L"Microsoft.UI.Private.Controls.FrameworkPackageDetector"sv}; winrt::IActivationFactory activationFactory; - *winrt::put_abi(activationFactory) = winrt_get_activation_factory(L"Microsoft.UI.Private.Controls.FrameworkPackageDetector"sv); - if (activationFactory) + if (SUCCEEDED(WINRT_RoGetActivationFactory(winrt::get_abi(typeName), winrt::guid_of(), winrt::put_abi(activationFactory)))) { return true; } diff --git a/dev/dll/dllmain.cpp b/dev/dll/dllmain.cpp index dd7de05e04..f6b2649104 100644 --- a/dev/dll/dllmain.cpp +++ b/dev/dll/dllmain.cpp @@ -28,6 +28,20 @@ STDAPI_(BOOL) DllMain(_In_ HINSTANCE hInstance, _In_ DWORD reason, _In_opt_ void HRESULT WINAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _Out_ ::IActivationFactory** factory) { + // This "FrameworkPackageDetector" class is a breadcrumb to help us detect if we're running in a framework package. + // The way this works is that our WinMD does not contain this type so attempting to activate it will fail. However, + // our framework package AppX contains an activatable class registration for it, so code that tries to activate + // it will succeed in that context. + uint32_t length{}; + wchar_t const* const buffer = WINRT_WindowsGetStringRawBuffer(activatableClassId, &length); + std::wstring_view const name{ buffer, length }; + if (name == L"Microsoft.UI.Private.Controls.FrameworkPackageDetector"sv) + { + winrt::hstring resources{L"Microsoft.UI.Xaml.Controls.XamlControlsResources"sv}; + // It doesn't matter *what* we return so return a type that everyone uses. + return WINRT_GetActivationFactory(winrt::get_abi(resources), reinterpret_cast(factory)); + } + return WINRT_GetActivationFactory(activatableClassId, reinterpret_cast(factory)); } diff --git a/idl/Microsoft.UI.Xaml.idl b/idl/Microsoft.UI.Xaml.idl index a1d64c5a8c..cd277764ca 100644 --- a/idl/Microsoft.UI.Xaml.idl +++ b/idl/Microsoft.UI.Xaml.idl @@ -153,20 +153,6 @@ namespace MU_X_XTI_NAMESPACE } } -namespace MU_PRIVATE_CONTROLS_NAMESPACE -{ - // This class is a breadcrumb to help us detect if we're running in a framework package. - // The way this works is that our WinMD does not contain this type so attempting to activate it - // will fail. However our framework package AppX contains an activatable class registration for - // it, so code that tries to activate it will succeed in that context. - [WUXC_VERSION_INTERNAL] - [webhosthidden] - [default_interface] - runtimeclass FrameworkPackageDetector - { - } -} - namespace MU_XC_NAMESPACE { [WUXC_VERSION_MUXONLY]