Cannot use an Xaml component from a C# WinRT Component in C++/WinRT Xaml Islands project

293 views Asked by At

How to replicate (we will use Windows Terminal as example):

  1. Clone the Windows Terminal repo and fetch submodules

  2. Create a C# Windows Runtime Component in the solution with a UserControl with some random controls

  3. Reference the C# WinRT Component from the project you want to host the UserControl in

  4. Open an Xaml page in one of Windows Terminal projects (we will use TerminalPage.xaml from TerminalAppLib project as an example)

  5. Add the UserControl to that page

  6. Compile and run (you might need to include the generated Xaml compiled files of the UserControl to pch.h file for it to compile without Xaml Compiler errors)

  7. You will find that the app will crash with class not registered exception

What I have tried:

  1. Using Class Library instead of WinRT Component

  2. https://a.rcad.io/csharp-in-cppwinrt

  3. https://github.com/asklar/WinRTComponent/blob/master/README.md

  4. Registering the class in WindowsTerminal.manifest file, like this (I used .dll instead of .winmd when I tried with Class Library):

<file name="myWinRTComponent.winmd" hashalg="SHA1" xmlns:winrt="urn:schemas-microsoft-com:winrt.v1">
    <winrt:activatableClass name="Namespace.UserControlClass" threadingModel="both" />
</file>
  1. Registering the class manually in AppxManifest.xml file
1

There are 1 answers

0
Ahmed Walid On BEST ANSWER

So I finally found the solution we have to register against CLRHost.dll instead of the Runtime Component Winmd file

So if the app is packaged we have to add that inside the Extensions tag (which is inside the Package tag not the one that inside the Application tag) of Package.appxmanifest (keeping in mind that Namespace is the namespace of the control and the Runtime Component name/assembly name & UserControlClass is the name of the UserControl class)

<Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>CLRHost.dll</Path>
        <ActivatableClass ActivatableClassId="Namespace.Namespace_XamlTypeInfo.XamlMetaDataProvider" ThreadingModel="both" />
        <ActivatableClass ActivatableClassId="Namespace.UserControlClass" ThreadingModel="both" />
      </InProcessServer>
</Extension>

And we have to add this to Application.manifest inside the assembly tag if the app is unpackaged (keeping in mind that Application is the name of the application & Namespace is the namespace of the control and the Runtime Component name/assembly name & UserControlClass is the name of the UserControl class)

<file name="CLRHost.dll" xmlns:winrt="urn:schemas-microsoft-com:winrt.v1">
    <winrt:activatableClass name="Namespace.Namespace_XamlTypeInfo.XamlMetaDataProvider" threadingModel="both"/>
    <winrt:activatableClass name="Namespace.UserControlClass" threadingModel="both"/>
</file>