操作实例 — 创建一个 C# /WinRT 组件并从 C++/WinRT 使用它

借助 C#/WinRT,.NET 开发人员能够使用类库项目在 C# 中创作自己的 Windows 运行时组件。 创作的组件可以在本机桌面应用程序中用作包引用或作为项目引用,但需要进行一些修改。

本演练演示了如何使用 C#/WinRT 创建一个简单的 Windows 运行时组件,将组件作为 NuGet 包分发,以及如何从 C++/WinRT 控制台应用程序使用该组件。 有关为本文提供代码的完整示例,请参阅 C#/WinRT 创作示例。 有关创作的更多详细信息,请参阅创作组件

有关使用 C#/WinRT 专门用于 Windows 应用 SDK 应用程序的 WinUI 控件的演练,请参阅文章演练:使用 WinUI 3 控件创作 C# 组件并从 C++ Windows 应用 SDK 应用程序使用

先决条件

本演练需要下列工具和组件:

使用 C#/WinRT 创建一个简单的 Windows 运行时组件

首先在 Visual Studio 中创建一个新项目。 选择类库项目模板,并将项目命名为 AuthoringDemo。 需要对项目进行以下添加和修改:

  1. 更新 AuthoringDemo.csproj 文件中的 TargetFramework 并将以下元素添加到 PropertyGroup

    <PropertyGroup>
        <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
        <Platforms>x64</Platforms>
    </PropertyGroup>
    

    若要访问 Windows 运行时类型,需要在 TFM 中设置特定的 Windows SDK 版本。 有关受支持的版本的更多详细信息,请参阅 .NET 6 及更高版本:使用 TFM 选项

  2. Microsoft.Windows.CsWinRT NuGet 包安装到项目中。

    a. 在“解决方案资源管理器”中,右键单击项目节点并选择“管理 NuGet 包”

    b. 搜索“Microsoft.Windows.CsWinRT”NuGet 包,并安装最新版本。 本演练使用 C#/WinRT 版本 1.4.1。

  3. 添加设置 CsWinRTComponent 属性的新 PropertyGroup 元素。 这指定项目是 Windows 运行时组件,因此生成项目时会生成 .winmd 文件。

    <PropertyGroup>   
        <CsWinRTComponent>true</CsWinRTComponent>
    </PropertyGroup>
    

    有关 C#/WinRT 项目属性的完整列表,请参阅 C#/WinRT NuGet 文档。

  4. 可以使用库 .cs 类文件创作运行时类。 右键单击 Class1.cs 文件,并将其重命名为 Example.cs。 将以下代码添加到此文件,这将向运行时类添加公共属性和方法。 请记住,将要在运行时组件中公开的任何类标记为 public

    namespace AuthoringDemo
    {
        public sealed class Example
        {
            public int SampleProperty { get; set; }
    
            public static string SayHello()
            {
                return "Hello from your C# WinRT component";
            }
        }
    }
    
  5. 现在可以构建项目,为组件生成 .winmd 文件。 右键单击解决方案资源管理器中的项目,然后单击生成。 你将在生成输出文件夹中看到生成的 AuthoringDemo.winmd 文件。

为组件生成 NuGet 包

大多数开发人员希望以 NuGet 包的形式分发和共享其 Windows 运行时组件。 另一个选项是将组件用作项目引用。 以下步骤演示如何打包 AuthoringDemo 组件。 生成包时,C#/WinRT 会配置包中的组件和托管程序集,以供本机应用程序使用。

有几种方法可以生成 NuGet 包:

  • 如果想在每次构建项目时生成 NuGet 包,请将以下属性添加到 AuthoringDemo 项目文件,然后重新构建项目

    <PropertyGroup>
        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    </PropertyGroup>
    
  • 或者,可以通过右键单击“解决方案资源管理器”中的“AuthoringDemo”项目并选择“包”来生成 NuGet 包

生成包时,“生成”窗口应指示 NuGet 包 AuthoringDemo.1.0.0.nupkg 已成功创建。 有关使用 .NET CLI 的 NuGet 包属性的更多详细信息,请参阅使用 dotnet CLI 创建包

从 C++/WinRT 应用使用组件

可以从任何与 Windows 运行时 (WinRT) 兼容的语言使用 C#/WinRT 创作的 Windows 运行时组件。 以下步骤演示了如何在 C++/WinRT 控制台应用程序中调用上述创作的组件。

注意

包引用或项目引用都支持从 C#/.NET 应用使用 C#/WinRT 组件。 此场景相当于使用任何普通 C# 类库,并且在大多数情况下不涉及 WinRT 激活。 从 C#/WinRT 1.3.5 开始,C# 使用者的项目引用需要 .NET 6。

  1. 将新的 C++/WinRT 控制台应用程序项目添加到解决方案中。 请注意,如果选择这样做,此项目也可以是其他解决方案的一部分。

    a. 在“解决方案资源管理器”中,右键单击你的解决方案节点,然后单击“添加”->“新建项目”

    b. 在“新建项目”对话框中,搜索“C++/WinRT 控制台应用程序”项目模板。 选择该模板,然后单击“下一步”

    c. 将新项目命名为 CppConsoleApp,然后单击“创建”

  2. 添加对 AuthoringDemo 组件的引用,作为 NuGet 包或项目引用。

    • 选项 1(包引用)

      a. 右键单击“CppConsoleApp”项目,然后选择“管理 NuGet 包”。 可能需要配置包源以添加对 AuthoringDemo NuGet 包的引用。 为此,请单击 NuGet 包管理器中的“设置”图标并将包源添加到相应的路径

      NuGet settings

      b. 配置包源后,搜索“AuthoringDemo”包并单击“安装”

      Install NuGet package

    • 选项 2(包引用)

      a. 右键单击“CppConsoleApp”项目并选择“添加”->“引用”。 在“项目”节点下,添加对 AuthoringDemo 项目的引用

  3. 若要托管组件,需要为可激活的类注册添加清单文件。 有关托管组件托管的更多详细信息,请参阅托管组件托管

    a. 若要添加清单文件,请再次右键单击该项目并选择“添加”->“新项目”。 搜索“文本文件”模板并将其命名为“CppConsoleApp.exe.manifest”。 粘贴以下内容,这些内容使用可激活的类注册条目指定运行时类:

    <?xml version="1.0" encoding="utf-8"?>
    <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
        <assemblyIdentity version="1.0.0.0" name="CppConsoleApp"/>
        <file name="WinRT.Host.dll">
            <activatableClass
                name="AuthoringDemo.Example"
                threadingModel="both"
                xmlns="urn:schemas-microsoft-com:winrt.v1" />
        </file>
    </assembly>
    

    未打包的应用需要应用程序清单文件。 对于打包的应用,应用使用者需要在其 Package.appxmanifest 包清单文件中注册可激活类,如演练:使用 WinUI 3 控件创建 C# 组件并从 C++ Windows App SDK 应用程序使用中所述。

    b. 修改项目以在部署项目时在输出中包含清单文件。 单击“解决方案资源管理器”中的“CppConsoleApp.exe.manifest”文件并将“Content”属性设置为“True”。 下面是该操作的一个示例。

    Deploy Content

  4. 打开项目头文件下的“pch.h”,并添加以下代码行以包含你的组件

    #include <winrt/AuthoringDemo.h>
    
  5. 打开项目源文件下的“main.cpp”,并将其替换为以下内容

    #include "pch.h"
    #include "iostream"
    
    using namespace winrt;
    using namespace Windows::Foundation;
    
    int main()
    {
        init_apartment();
    
        AuthoringDemo::Example ex;
        ex.SampleProperty(42);
        std::wcout << ex.SampleProperty() << std::endl;
        std::wcout << ex.SayHello().c_str() << std::endl;
    }
    
  6. 生成并运行 CppConsoleApp 项目。 现在,你应会看到以下输出。

    C++/WinRT Console output