共用方式為


撰寫 C# Windows 執行階段元件以從 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) 檔案的建置步驟。 這是 Visual Studio 會包含在您的應用程式中的 Windows 執行階段元件 (WRC)。

注意

.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 Basic 專案新增至解決方案。 在 [新增新的專案] 對話方塊的 [安裝的範本] 區段中,選擇 [Visual C#],然後選擇 [Windows],再選擇 [通用]。 選擇 [Windows 執行階段元件 (通用 Windows)] 範本,並針對專案名稱輸入 SampleComponent

注意

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

新增 C# GetMyString 方法

SampleComponent 專案中,將類別的名稱從 Class1 變更為 Example。 然後將兩個簡單成員新增至類別、私人 int 欄位,以及名為 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

CppToCSharpWinRT 專案中開啟 MainPage.h,然後新增兩個項目。 請先在 #include 陳述式結尾新增 #include "winrt/SampleComponent.h",然後將 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# (受控) 和 C++ (原生) 程式碼進行偵錯,請將偵錯工具類型設定為 [受控和原生]C++偵錯屬性

應用程式最低版本

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

提示

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

針對 Windows 10 Fall Creators Update (10.0;組建 16299) 進行設定

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

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

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

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

   <!-- 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 變數 Directory 範例
DotNetNativeVersion %ProgramFiles(x86)%\Microsoft SDKs\UWPNuGetPackages\Microsoft.Net.Native.Compiler 2.2.12-rel-31116-00
DotNetNativeSharedLibrary %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>