共用方式為


撰寫 C# Windows Runtime 元件以供 C++/WinRT 應用程式使用

本主題將引導您將簡單的 C# 元件新增至 C++/WinRT 專案的過程。

Visual Studio 可讓您輕鬆地在以 C# 或 Visual Basic 撰寫的 Windows 執行時間元件 (WRC) 專案中撰寫並部署您自己的自定義 Windows 運行時間類型,然後從C++應用程式專案參考該 WRC,以及從該應用程式取用這些自定義類型。

在內部,您的 Windows 執行階段類型可以使用任何在 UWP 應用程式中允許的 .NET 功能。

你這個類型的成員在對外暴露時,只能公開 Windows 運行時類型作為其參數和返回值。 當您建置方案時,Visual Studio 會建置 .NET WRC 專案,然後執行建立 Windows 元數據 (.winmd) 檔案的建置步驟。 這是您的 Windows 執行階段元件(WRC),這個元件已由 Visual Studio 包含在您的應用程式中。

備註

.NET 會自動將一些常用的 .NET 類型,例如基本數據類型和集合類型,對應至其 Windows 運行時間對等專案。 這些 .NET 類型可以用於 Windows 執行階段元件的公用介面,並將以對應的 Windows 執行階段類型呈現給元件的使用者。 請參閱 使用 C# 和 Visual Basic 的 Windows 執行階段元件

先決條件

建立空白應用程式

在 Visual Studio 中,使用 空白應用程式 (C++/WinRT) 項目範本建立新專案。 請確定您使用 (C++/WinRT) 範本,而不是 (通用 Windows) 範本。

將新專案的名稱設定為 CppToCSharpWinRT,讓資料夾結構符合逐步解說。

將 C# Windows 執行時間元件新增至解決方案

在 Visual Studio 中,建立元件專案:在方案總管中,開啟 CppToCSharpWinRT 方案的快捷方式功能表,然後選擇 [新增] ,然後選擇 [新增專案],將新的 C# 專案新增至方案。 在 [新增專案] 對話框的 [已安裝 的範本] 區段中,選擇 [visual C#] ,然後選擇 [Windows],然後 通用。 選擇 Windows 執行階段元件(通用 Windows) 範本,然後將 SampleComponent 作為專案名稱輸入。

備註

在 [新的通用 Windows 平台專案] 對話框中,選擇 [Windows 10 Creators Update (10.0;組建 15063) 為最低版本。 如需詳細資訊,請參閱下方 應用程式最低版本 一節。

新增 C# GetMyString 方法

SampleComponent 專案中,將 類別的名稱從 Class1 變更為 Example。 然後將兩個簡單成員新增至類別,包括一個私人 欄位,以及一個名為 GetMyString的實例方法:

    public sealed class Example
    {
        int MyNumber;

        public string GetMyString()
        {
            return $"This is call #: {++MyNumber}";
        }
    }

備註

根據預設,類別會標示 公用密封。 您從元件公開的所有 Windows 執行時間類別,都必須 密封

備註

選用:若要為新加入的成員啟用 IntelliSense,請在 [方案總管] 中開啟 SampleComponent 專案的右鍵選單,然後選擇 [建置]。

在 CppToCSharpWinRT 專案中參考 C# SampleComponent

在 [方案總管] 的 C++/WinRT 專案中,開啟 [參考]的快捷方式功能表,然後選擇 [新增參考] 來開啟 [[新增參考] 對話框。 選擇 [項目],然後選擇 [方案]。 選取 SampleComponent 項目的複選框,然後選擇 [確定] 來新增參考。

備註

選用:若要為 C++/WinRT 專案啟用 IntelliSense,請在 [方案總管] 中,開啟 CppToCSharpWinRT 專案的快捷方式功能表,然後選擇 [建置]。

編輯MainPage.h

MainPage.h 專案中開啟 ,然後新增兩個項目。 請先在 #include "winrt/SampleComponent.h" 語句結尾新增 #include,然後將 winrt::SampleComponent::Example 字段新增至 MainPage 結構。

// MainPage.h
...
#include "winrt/SampleComponent.h"

namespace winrt::CppToCSharpWinRT::implementation
{
    struct MainPage : MainPageT<MainPage>
    {
...
        winrt::SampleComponent::Example myExample;
...
    };
}

備註

在 Visual Studio 中,MainPage.h 列在 MainPage.xaml底下。

編輯MainPage.cpp

MainPage.cpp中,將 Mainpage::ClickHandler 實作變更為呼叫 C# 方法 GetMyString

void MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
{
    //myButton().Content(box_value(L"Clicked"));

    hstring myString = myExample.GetMyString();

    myButton().Content(box_value(myString));
}

執行專案

您現在可以建置並執行專案。 每次按鍵時,按鈕中的數位將會遞增。

C++/WinRT Windows 呼叫 C# 元件螢幕快照

小提示

在 Visual Studio 中,建立元件專案:在 [方案總管] 中,開啟 CppToCSharpWinRT專案的快捷方式功能表,然後選擇 [屬性],然後選擇 [偵錯] 下的 [組態屬性]。 如果您想要偵錯 C# (managed) 和 C++ (native) 程式代碼,請將調試程式類型設定為 Managed 和 NativeC++ 偵錯屬性

應用程式最低版本

C# 專案版本的 應用程式最低 將控制用來編譯應用程式的 .NET 版本。 例如,選擇 Windows 10 Fall Creators Update (10.0;組建 16299) 或更新版本將會啟用 .NET Standard 2.0 和 Windows Arm64 處理器支援。

小提示

建議如果不需要 .NET Standard 2.0 或 Arm64 支援,使用低於 16299 的應用程式最低 版本,以避免額外的建置配置。

設定 Windows 10 秋季創作者更新(10.0; 版本 16299)

請遵循下列步驟,在從C++/WinRT 項目參考的 C# 專案中啟用 .NET Standard 2.0 或 Windows Arm64 支援。

在 Visual Studio 中,移至 [方案總管],然後開啟 CppToCSharpWinRT 專案的快捷方式功能表。 選擇 [屬性],並將 [通用 Windows App 最低版本] 設定為 Windows 10 Fall Creators Update (10.0; 組建 16299) (或更新版本)。 針對 SampleComponent 項目執行相同的動作。

在 Visual Studio 中,開啟 CppToCSharpWinRT 專案的快捷方式功能表,然後選擇 [卸除專案],以在文字編輯器中開啟 CppToCSharpWinRT.vcxproj

將下列 XML 複製並貼到 PropertyGroup中的第一個 CPPWinRTCSharpV2.vcxproj

   <!-- Start Custom .NET Native properties -->
   <DotNetNativeVersion>2.2.12-rel-31116-00</DotNetNativeVersion>
   <DotNetNativeSharedLibrary>2.2.8-rel-31116-00</DotNetNativeSharedLibrary>
   <UWPCoreRuntimeSdkVersion>2.2.14</UWPCoreRuntimeSdkVersion>
   <!--<NugetPath>$(USERPROFILE)\.nuget\packages</NugetPath>-->
   <NugetPath>$(ProgramFiles)\Microsoft SDKs\UWPNuGetPackages</NugetPath>
   <!-- End Custom .NET Native properties -->

DotNetNativeVersionDotNetNativeSharedLibraryUWPCoreRuntimeSdkVersion 的值可能會因Visual Studio版本而異。 若要將它們設定為正確的值,請開啟 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages,並查看下表中每個值的子目錄。 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler 目錄會有子目錄,其中包含以 2.2開頭的已安裝 .NET 原生版本。 在下列範例中,它是 2.2.12-rel-31116-00

MSBuild 變數 目錄 範例
DotNetNativeVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler 2.2.12-rel-31116-00
.NET原生共享庫 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-x64.microsoft.net.native.sharedlibrary 2.2.8-rel-31116-00
UWPCoreRuntimeSdkVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.UWPCoreRuntimeSdk 2.2.14

備註

Microsoft.Net.Native.SharedLibrary 有多個支持的架構。 將 x64 替換為適當的架構。 例如,arm64 架構會位於 %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\runtime.win10-arm64.microsoft.net.native.sharedlibrary 目錄中。

接下來,緊接在第一個 PropertyGroup之後,新增下列內容(未更改)。

  <!-- Start Custom .NET Native targets -->
  <!-- Import all of the .NET Native / CoreCLR props at the beginning of the project -->
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x86.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x64.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm64.Microsoft.Net.Native.Compiler.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary.props" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary.props" />
  <!-- End Custom .NET Native targets -->

在專案檔結尾處,緊接在結尾 Project 標籤之前,新增以下內容,且不得修改。

  <!-- Import all of the .NET Native / CoreCLR targets at the end of the project -->
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x86.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-x64.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk\$(UWPCoreRuntimeSdkVersion)\build\runtime.win10-arm.Microsoft.Net.UWPCoreRuntimeSdk.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x86.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-x64.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.Compiler\$(DotNetNativeVersion)\build\runtime.win10-arm64.Microsoft.Net.Native.Compiler.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x86.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-x64.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm.Microsoft.Net.Native.SharedLibrary.targets" />
  <Import Condition="'$(WindowsTargetPlatformMinVersion)' &gt;= '10.0.16299.0'" Project="$(NugetPath)\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary\$(DotNetNativeSharedLibrary)\build\runtime.win10-arm64.Microsoft.Net.Native.SharedLibrary.targets" />
  <!-- End Custom .NET Native targets -->

在 Visual Studio 中重載項目檔。 若要這樣做,請在 Visual Studio [方案總管] 中,開啟 CppToCSharpWinRT 專案的右鍵選單,然後選擇 [重載專案]

建置 .NET Native 專案

建議使用以 .NET 原生建置的 C# 元件來建置及測試您的應用程式。 在 Visual Studio 中,開啟 CppToCSharpWinRT 專案的快捷方式功能表,然後選擇 [卸除專案],以在文字編輯器中開啟 CppToCSharpWinRT.vcxproj

接下來,將 UseDotNetNativeToolchain 屬性設定為 C++ 項目檔中 Release 和 Arm64 組態中的 true

在 Visual Studio 方案總管中,開啟 CppToCSharpWinRT 專案的快捷方式功能表,然後選擇 [重載專案]

  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
...
    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Platform)'=='Arm64'" Label="Configuration">
    <UseDotNetNativeToolchain Condition="'$(UseDotNetNativeToolchain)'==''">true</UseDotNetNativeToolchain>
  </PropertyGroup>

參考其他 C# NuGet 套件

如果 C# 元件參考其他 nuget 套件,則應用程式的項目檔可能需要從 nuget 套件列出檔案相依性作為部署內容。 例如,如果 C# 元件參考 Newtonsoft.Json nuget 套件,則應用程式專案中也應該參考相同的 nuget 套件和檔案相依性。

SampleComponent.csproj 檔案中,新增 NuGet 套件引用:

    <PackageReference Include="Newtonsoft.Json">
      <Version>13.0.1</Version>
    </PackageReference>

CppToCSharpWinRT 專案中,找出 packages.config 檔案並新增適當的 nuget 參考。 這會將 nuget 套件安裝到解決方案的套件資料夾中。

packages.config中,新增相同的 nuget 套件參考:

  <package id="Newtonsoft.Json" version="13.0.1" targetFramework="native" developmentDependency="true" />

然後將下列內容新增至應用程式項目檔,以從解決方案的套件資料夾參考適當的檔案相依性。 例如,在 CppToCSharpWinRT.vcxproj 中新增以下內容:

  <ItemGroup>
    <None Include="..\packages\Newtonsoft.Json.13.0.1\lib\netstandard2.0\Newtonsoft.Json.dll">
      <Link>%(Filename)%(Extension)</Link>
      <DeploymentContent>true</DeploymentContent>
    </None>
  </ItemGroup>