无法在 C++/WinRT Xaml Islands 项目中使用来自 C# WinRT 组件的 Xaml 组件
Cannot use an Xaml component from a C# WinRT Component in C++/WinRT Xaml Islands project
如何复制(我们将以Windows终端为例):
克隆 Windows 终端仓库并获取子模块
在解决方案中创建一个 C# Windows 运行时组件 UserControl
带有一些随机控件
从要在
中托管 UserControl
的项目中引用 C# WinRT 组件
在 Windows 终端项目之一中打开一个 Xaml 页面(我们将使用 TerminalAppLib
项目中的 TerminalPage.xaml
作为示例)
将 UserControl
添加到该页面
编译和运行(您可能需要将UserControl
生成的Xaml编译文件包含到pch.h
文件中才能编译没有 Xaml 编译器错误)
您会发现该应用程序会崩溃并出现 class not registered
异常
我尝试过的:
使用 Class Library
代替 WinRT Component
-
https://github.com/asklar/WinRTComponent/blob/master/README.md
在 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>
- 正在
AppxManifest.xml
文件中手动注册 class
所以我终于找到了解决办法
我们必须针对 CLRHost.dll
而不是运行时组件 Winmd 文件
进行注册
因此,如果应用程序是 packaged,我们必须将其添加到 Extensions
标签(位于 Package
标记而不是 Package.appxmanifest
的 Application
标记内的标记)(请记住 Namespace
是控件 和 [=38= 的命名空间] 运行时组件 name/assembly 名称 & UserControlClass
是 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>
如果应用程序 未打包,我们必须将其添加到 assembly
标签内的 Application.manifest
(请记住 Application
是应用程序的名称 & Namespace
是控件的名称空间 和 运行时组件 name/assembly 名称 & UserControlClass
是 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>
如何复制(我们将以Windows终端为例):
克隆 Windows 终端仓库并获取子模块
在解决方案中创建一个 C# Windows 运行时组件
UserControl
带有一些随机控件从要在
中托管UserControl
的项目中引用 C# WinRT 组件在 Windows 终端项目之一中打开一个 Xaml 页面(我们将使用
TerminalAppLib
项目中的TerminalPage.xaml
作为示例)将
UserControl
添加到该页面编译和运行(您可能需要将
UserControl
生成的Xaml编译文件包含到pch.h
文件中才能编译没有 Xaml 编译器错误)您会发现该应用程序会崩溃并出现
class not registered
异常
我尝试过的:
使用
Class Library
代替WinRT Component
https://github.com/asklar/WinRTComponent/blob/master/README.md
在
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>
- 正在
AppxManifest.xml
文件中手动注册 class
所以我终于找到了解决办法
我们必须针对 CLRHost.dll
而不是运行时组件 Winmd 文件
因此,如果应用程序是 packaged,我们必须将其添加到 Extensions
标签(位于 Package
标记而不是 Package.appxmanifest
的 Application
标记内的标记)(请记住 Namespace
是控件 和 [=38= 的命名空间] 运行时组件 name/assembly 名称 & UserControlClass
是 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>
如果应用程序 未打包,我们必须将其添加到 assembly
标签内的 Application.manifest
(请记住 Application
是应用程序的名称 & Namespace
是控件的名称空间 和 运行时组件 name/assembly 名称 & UserControlClass
是 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>