我目前有一个工作项目,我正在使用 免注册 Winrt 在 win32 控制台应用程序中使用 C# WinRT 组件。一切工作正常,但当我尝试使用 C# 组件中的异步方法时,问题就出现了。由于
Task
不是 WinRT 类型,因此我四处寻找解决方案。那么从 C# WinRT 组件调用异步方法的正确方法是什么?
我使用 winmdidl.exe 和 midlrt.exe 为控制台应用程序创建 WinRT comp 头文件。我还包含了“Winrt/Windows.Foundation.h”。
我尝试过“如何在 Windows 运行时组件中公开异步方法”。这将构建,但在运行时会出现令人畏惧的错误(imo)
Class not registered
。这也是2014年的。
C# WinRT 组件:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
namespace MyComp
{
public sealed class MyLib
{
public static string OtherMethods() // only working method
{
return "string";
}
// Below methods results with `Class not registered` error
public static IAsyncOperation<string> TestAsync() // I think this is the problem
{
return TestAsyncHelper().AsAsyncOperation();
}
private static async Task<string> TestAsyncHelper()
{
// do stuff here
return "string";
}
// ******* Update ****
public static IDictionary<int, string> GetMapOfNames()
{
Dictionary<int, string> retval = new Dictionary<int, string>();
retval.Add(1, "one");
retval.Add(2, "two");
retval.Add(3, "three");
retval.Add(42, "forty-two");
retval.Add(100, "one hundred");
return retval;
}
}
}
我注意到每个非原始的 WinRT 类型都会发生这种情况。我正在尝试实现
IList<int>
或 IDictionary<int, string>
,但这些都不起作用。我发现 “将托管类型传递到 Windows 运行时” 导致 “从组件返回托管类型”,但我尝试的每一次尝试都导致了 Class not registered
错误。在链接的文章中,它提到当将 .Net 类型传递给 WinRT 组件时,它会在另一端显示为相应的 WinRT 类型,这听起来应该可以工作。我也尝试过使用 IMap<int, string>
,但是 IMap<K, V> is inaccessible due to its protection level
会出错。我已经更新了示例代码。
我知道已经晚了几年,也许你自己已经找到了解决方案,但我也遇到了同样的问题几天并意识到了解决方案。
查看 CsWinRT 项目中的一些示例后,尤其是 AuthoringDemo,它有一个使用 C#/WinRT 项目 (AuthoringDemo) 的 C++ 控制台应用程序 (CppConsoleApp),我意识到我错过了标签的声明
<CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
存在于文件中 AuthoringDemo/AuthoringDemo.csproj
。此标记在 CsWinRT 文档中描述为 “指定 Windows 元数据的源”,其默认值应为 $(WindowsSDKVersion)
,但似乎从未设置此值,并且 C#/WinRT 投影也没有设置无法导出一些运行时声明。
使用正确的 SDK 版本添加此标签后(取决于您的项目设置),它识别
IAsyncAction
、IList<>
和 IAsncOperation<>
以及可能所有其他运行时非原始投影。这个 AuthoringDemo.csproj 应该包含正确导出到 WinRT 所需的所有内容。
还值得注意的是,CppConsoleApp 有一个清单文件CppConsoleApp.exe.manifest,它必须声明您希望 WinRT 激活的 C# 类。您的 C++ 应用程序也应该类似。