无法在 C++/WinRT Xaml Islands 项目中使用来自 C# WinRT 组件的 Xaml 组件

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

如何复制(我们将以Windows终端为例):

  1. 克隆 Windows 终端仓库并获取子模块

  2. 在解决方案中创建一个 C# Windows 运行时组件 UserControl 带有一些随机控件

  3. 从要在

    中托管 UserControl 的项目中引用 C# WinRT 组件
  4. 在 Windows 终端项目之一中打开一个 Xaml 页面(我们将使用 TerminalAppLib 项目中的 TerminalPage.xaml 作为示例)

  5. UserControl 添加到该页面

  6. 编译和运行(您可能需要将UserControl生成的Xaml编译文件包含到pch.h文件中才能编译没有 Xaml 编译器错误)

  7. 您会发现该应用程序会崩溃并出现 class not registered 异常

我尝试过的:

  1. 使用 Class Library 代替 WinRT Component

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

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

  4. WindowsTerminal.manifest 文件中注册 class,就像这样(当我尝试使用 [=21= 时,我使用 .dll 而不是 .winmd ]):

<file name="myWinRTComponent.winmd" hashalg="SHA1" xmlns:winrt="urn:schemas-microsoft-com:winrt.v1">
    <winrt:activatableClass name="Namespace.UserControlClass" threadingModel="both" />
</file>
  1. 正在 AppxManifest.xml 文件中手动注册 class

所以我终于找到了解决办法 我们必须针对 CLRHost.dll 而不是运行时组件 Winmd 文件

进行注册

因此,如果应用程序是 packaged,我们必须将其添加到 Extensions 标签(位于 Package 标记而不是 Package.appxmanifestApplication 标记内的标记)(请记住 Namespace 是控件 和 [=38= 的命名空间] 运行时组件 name/assembly 名称 & UserControlClassUserControl 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>

如果应用程序 未打包,我们必须将其添加到 assembly 标签内的 Application.manifest (请记住 Application 是应用程序的名称 & Namespace 是控件的名称空间 运行时组件 name/assembly 名称 & UserControlClassUserControl 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>