Skip to content

Commit

Permalink
Fix IsInFrameworkPackage logic (#1762)
Browse files Browse the repository at this point in the history
  • Loading branch information
jevansaks authored Dec 16, 2019
1 parent f5355bf commit 52571ee
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 28 deletions.
8 changes: 0 additions & 8 deletions dev/dll/MUXControlsFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 7 additions & 6 deletions dev/dll/SharedHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<IActivationFactory>(), winrt::put_abi(activationFactory))))
{
return true;
}
Expand Down
14 changes: 14 additions & 0 deletions dev/dll/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<void**>(factory));
}

return WINRT_GetActivationFactory(activatableClassId, reinterpret_cast<void**>(factory));
}

Expand Down
14 changes: 0 additions & 14 deletions idl/Microsoft.UI.Xaml.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 52571ee

Please sign in to comment.