このトピックでは、 C#/WinRT を使用して C++/WinRT Windows ランタイム コンポーネントから C# .NET プロジェクション (または相互運用) アセンブリを生成し、それを .NET アプリケーション用の NuGet パッケージとして配布する方法について説明します。
.NET 6 以降では、Windows メタデータ (WinMD) ファイルの使用はサポートされなくなりました ( WinRT の組み込みサポートが .NET から削除されるを参照)。 代わりに、C#/WinRT ツールを使用して任意の WinMD ファイルのプロジェクション アセンブリを生成できます。これにより、.NET アプリケーションから WinRT コンポーネントを使用できるようになります。 プロジェクション アセンブリは相互運用機能アセンブリとも呼ばれます。 このチュートリアルでは、次の操作を行う方法について説明します。
- C#/WinRT パッケージを使用して、C++/WinRT コンポーネントから C# プロジェクションを生成します。
- コンポーネントをプロジェクション アセンブリと共に NuGet パッケージとして配布します。
- .NET コンソール アプリケーションから NuGet パッケージを使用します。
[前提条件]
このチュートリアルと対応するサンプルには、次のツールとコンポーネントが必要です。
- Visual Studio 2022(または Visual Studio 2019)にユニバーサル Windows プラットフォーム開発ワークロードがインストールされている。 インストールの詳細>Universal Windows プラットフォーム開発で、C++ (v14x) ユニバーサル Windows プラットフォーム ツール オプションをオンにします。
- .NET 6.0 SDK 以降を使用します。
Visual Studio 2019 のみ。 C++/WinRT VSIX 拡張機能。Visual Studio で C++/WinRT プロジェクト テンプレートを提供します。 プロジェクト テンプレートは Visual Studio 2022 に組み込まれています。
このチュートリアルでは、Visual Studio 2022 と .NET 6 を使用します。
Von Bedeutung
また、GitHub の C#/WinRT プロジェクション サンプルから、このトピックのサンプル コードをダウンロードまたは複製する必要があります。
CsWinRT にアクセスし、緑色の [コード] ボタンをクリックしてgit clone
URL を取得します。 サンプルの README.md ファイルを必ず読んでください。
単純な C++/WinRT Windows ランタイム コンポーネントを作成する
このチュートリアルに従うには、まず C# プロジェクション アセンブリの生成元となる C++/WinRT Windows ランタイム コンポーネント (WRC) が必要です。
このチュートリアルでは、既にダウンロードまたは複製した GitHub 上の C#/WinRT プロジェクション サンプルの SimpleMathComponent WRC を使用します。 SimpleMathComponent は 、Windows ランタイム コンポーネント (C++/WinRT) Visual Studio プロジェクト テンプレート (Visual Studio 2022 または C++/WinRT VSIX 拡張機能に付属) から作成されました。
Visual Studio で SimpleMathComponent プロジェクトを開くには、 \CsWinRT\src\Samples\NetProjectionSample\CppWinRTComponentProjectionSample.sln
ファイルを開きます。このファイルは、リポジトリのダウンロードまたは複製にあります。
このプロジェクトのコードは、以下のヘッダー ファイルに示されている基本的な算術演算の機能を提供します。
// SimpleMath.h
...
namespace winrt::SimpleMathComponent::implementation
{
struct SimpleMath: SimpleMathT<SimpleMath>
{
SimpleMath() = default;
double add(double firstNumber, double secondNumber);
double subtract(double firstNumber, double secondNumber);
double multiply(double firstNumber, double secondNumber);
double divide(double firstNumber, double secondNumber);
};
}
SimpleMathComponent C++/WinRT Windows ランタイム コンポーネント プロジェクトで、Windows Desktop Compatible プロパティが [はい] に設定されていることを確認できます。 これを行うには、 SimpleMathComponent のプロジェクト プロパティの [構成プロパティ>General>Project の既定値で、 Windows Desktop 互換 プロパティを [はい] に設定します。 これにより、.NET デスクトップ アプリを使用するために適切なランタイム バイナリが読み込まれます。
C++/WinRT コンポーネントの作成と WinMD ファイルの生成の詳細な手順については、「 C++/WinRT を使用した Windows ランタイム コンポーネント」を参照してください。
注
コンポーネント
プロジェクション プロジェクトをコンポーネント ソリューションに追加する
まず、 CppWinRTComponentProjectionSample ソリューションを Visual Studio で開いたままにして、そのソリューションから SimpleMathProjection プロジェクトを削除します。 その後、ファイル システムから SimpleMathProjection フォルダーを削除します (または、必要に応じて名前を変更します)。 これらの手順は、このチュートリアルの手順に従うことができるように必要です。
新しい C# ライブラリ プロジェクトをソリューションに追加します。
- ソリューション エクスプローラー
で、ソリューション ノードを右クリックし、[新しいプロジェクト 追加] クリックします。 - [新しいプロジェクト の追加] ダイアログ ボックスで、検索ボックスに「クラス ライブラリ」と入力します。 言語の一覧から C# を選択し、プラットフォームの一覧から Windows を選択します。 クラス ライブラリ (プレフィックスもサフィックスも付かない)
呼び出される C# プロジェクト テンプレートを選択し、[次へ] クリックします。 - 新しいプロジェクトに SimpleMathProjection という名前を付けます。 この場所は、
\CsWinRT\src\Samples\NetProjectionSample
フォルダーと同じ フォルダーに既に設定されている必要がありますが、確認してください。 続けて、 [次へ] をクリックします。 - [ 追加情報 ] ページ で、[.NET 6.0 (長期サポート)]、[ 作成] の順に選択します。
- ソリューション エクスプローラー
スタブ Class1.cs ファイルをプロジェクトから削除します。
C#/WinRT NuGet パッケージをインストールするには、次の手順に従います。
- ソリューション エクスプローラーで SimpleMathProjection プロジェクトを右クリックし、[NuGet パッケージの管理]を選択します。
- [ 参照 ] タブで、 Microsoft.Windows.CsWinRT を入力するか、検索ボックスに貼り付けます。検索結果で最新バージョンのアイテムを選択し、[ インストール ] をクリックしてパッケージを SimpleMathProjection プロジェクトにインストールします。
SimpleMathProjection に、SimpleMathComponent プロジェクトへの参照を追加します。 ソリューション エクスプローラー
で、 SimpleMathProjection プロジェクト ノードの下にある [依存関係 ] ノードを右クリックし、[プロジェクト参照の追加]選択し、[OK] [ 。SimpleMathComponent プロジェクトを選択
まだプロジェクトをビルドしないでください。 これは後の手順で行います。
ここまでは、 ソリューション エクスプローラー は次のようになります (バージョン番号は異なります)。
ソースからプロジェクトをビルドする
C#/WinRT プロジェクション サンプルの CppWinRTComponentProjectionSample ソリューション (GitHub からダウンロードまたは複製し、現在は開いている) の場合、ビルド出力の場所は、ソースからビルドするように Directory.Build.props ファイルで構成されます。 つまり、ビルド出力のファイルはソース フォルダーの外部で生成されます。 C#/WinRT ツールを使用するときは、ソースからビルドすることをお勧めします。 これにより、C# コンパイラがプロジェクト ルート ディレクトリの下にあるすべての *.cs ファイルを誤って取得するのを防ぐことができます。これにより、重複する型エラーが発生する可能性があります (たとえば、複数の構成やプラットフォーム用にコンパイルする場合)。
これは 既に CppWinRTComponentProjectionSample ソリューション用に構成されていますが、次の手順に従って、自分で構成を実行する方法を確認してください。
ソースからビルドするようにソリューションを構成するには:
CppWinRTComponentProjectionSample ソリューションを開いたままで、ソリューション ノードを右クリックし、[>新しい項目] を追加して選択します。
XML ファイル 項目を選択し、directory.Build.props名前を付けます (拡張子 付けはありません)。 [はい] をクリックして既存のファイルを上書きします。 Directory.Build.props の内容を次の構成に置き換えます。
<Project> <PropertyGroup> <BuildOutDir>$([MSBuild]::NormalizeDirectory('$(SolutionDir)', '_build', '$(Platform)', '$(Configuration)'))</BuildOutDir> <OutDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin'))</OutDir> <IntDir>$([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj'))</IntDir> </PropertyGroup> </Project>
Directory.Build.props ファイルを保存して閉じます。
プロジェクト ファイルを編集して C#/WinRT を実行する
cswinrt.exe
ツールを呼び出してプロジェクション アセンブリを生成するには、まずプロジェクト ファイルを編集して、いくつかのプロジェクト プロパティを指定する必要があります。
ソリューション エクスプローラーで、SimpleMathProjection ノードをダブルクリックして、エディターでプロジェクト ファイルを開きます。
特定の Windows SDK バージョンをターゲットにするように
TargetFramework
要素を更新します。 これにより、相互運用とプロジェクションのサポートに必要なアセンブリの依存関係が追加されます。 このサンプルは、Windows SDK バージョン net6.0-windows10.0.19041.0 (Windows 10 バージョン 2004 とも呼ばれます) を対象としています。 結果のプロジェクション アセンブリを任意のアプリ アーキテクチャから参照できるように、Platform
要素を AnyCPU に設定します。 アプリケーションを参照して以前のバージョンの Windows SDK をサポートできるようにするには、TargetPlatformMinimumVersion
プロパティを設定することもできます。<PropertyGroup> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <!-- Set Platform to AnyCPU to allow consumption of the projection assembly from any architecture. --> <Platform>AnyCPU</Platform> </PropertyGroup>
注
このチュートリアルと関連するサンプルコードでは、ソリューションは x64 および Release用に構築されています。 SimpleMathProjection プロジェクトは、すべてのソリューション アーキテクチャ構成で AnyCPU 用にビルドするように構成されていることに注意してください。
複数の C#/WinRT プロパティを設定する 2 つ目の
PropertyGroup
要素 (最初の要素の直後) を追加します。<PropertyGroup> <CsWinRTIncludes>SimpleMathComponent</CsWinRTIncludes> <CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir> </PropertyGroup>
この例の設定の詳細を次に示します。
-
CsWinRTIncludes
プロパティは、プロジェクトする名前空間を指定します。 -
CsWinRTGeneratedFilesDir
プロパティは、プロジェクション ソース ファイルが生成される出力ディレクトリを設定します。 このプロパティは、上記のセクションのOutDir
で定義されているに設定されます。
-
SimpleMathProjection.csproj ファイルを保存して閉じ、必要に応じてクリックしてプロジェクトを 再読み込み します。
プロジェクションを使用して NuGet パッケージを作成する
.NET アプリケーション開発者向けにプロジェクション アセンブリを配布するには、いくつかのプロジェクト プロパティを追加することで、ソリューションをビルドするときに NuGet パッケージを自動的に作成できます。 .NET ターゲットの場合、NuGet パッケージには、コンポーネントのプロジェクション アセンブリと実装アセンブリを含める必要があります。
次の手順を使用して、NuGet 仕様 (
.nuspec
) ファイルを SimpleMathProjection プロジェクトに追加します。- ソリューション エクスプローラー
で、 SimpleMathProjection ノードを右クリック、[新しいフォルダー 追加] を選択し、nuget フォルダー 名前を付けます。 - nuget フォルダーを右クリックし、[追加>新しいアイテム] を選択し、[XML ファイル] を選択し、SimpleMathProjection.nuspec という名前を付けます。
- ソリューション エクスプローラー
ソリューション エクスプローラーで、SimpleMathProjection ノードをダブルクリックして、エディターでプロジェクト ファイルを開きます。 現在開いている SimpleMathProjection.csproj (2 つの既存の
PropertyGroup
要素の直後) に次のプロパティ グループを追加して、パッケージを自動的に生成します。 これらのプロパティは、NuGet パッケージを生成するNuspecFile
とディレクトリを指定します。<PropertyGroup> <GeneratedNugetDir>.\nuget\</GeneratedNugetDir> <NuspecFile>$(GeneratedNugetDir)SimpleMathProjection.nuspec</NuspecFile> <OutputPath>$(GeneratedNugetDir)</OutputPath> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> </PropertyGroup>
注
パッケージを個別に生成する場合は、コマンド ラインから
nuget.exe
ツールを実行することもできます。 NuGet パッケージの作成の詳細については、「 nuget.exe CLI を使用したパッケージの作成」を参照してください。SimpleMathProjection.nuspec ファイルを開いてパッケージ作成プロパティを編集し、次のコードを貼り付けます。 次のスニペットは、 SimpleMathComponent を複数のターゲット フレームワークに配布するための NuGet 仕様の例です。 ターゲット の
lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll
の代わりに、プロジェクション アセンブリSimpleMathProjection.dllが指定されていることに注意してください。 この動作は .NET 6 以降では新しく、C#/WinRT によって有効になっています。 実装アセンブリSimpleMathComponent.dll
も配布する必要があり、実行時に読み込まれます。<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <metadata> <id>SimpleMathComponent</id> <version>0.1.0-prerelease</version> <authors>Contoso Math Inc.</authors> <description>A simple component with basic math operations</description> <dependencies> <group targetFramework="net6.0-windows10.0.19041.0" /> <group targetFramework=".NETCoreApp3.0" /> <group targetFramework="UAP10.0" /> <group targetFramework=".NETFramework4.6" /> </dependencies> </metadata> <files> <!--Support .NET 6, .NET Core 3, UAP, .NET Framework 4.6, C++ --> <!--Architecture-neutral assemblies--> <file src="..\..\_build\AnyCPU\Release\SimpleMathProjection\bin\SimpleMathProjection.dll" target="lib\net6.0-windows10.0.19041.0\SimpleMathProjection.dll" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\netcoreapp3.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\uap10.0\SimpleMathComponent.winmd" /> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.winmd" target="lib\net46\SimpleMathComponent.winmd" /> <!--Architecture-specific implementation DLLs should be copied into RID-relative folders--> <file src="..\..\_build\x64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x64\native\SimpleMathComponent.dll" /> <!--To support x86 and Arm64, build SimpleMathComponent for those other architectures and uncomment the entries below.--> <!--<file src="..\..\_build\Win32\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-x86\native\SimpleMathComponent.dll" />--> <!--<file src="..\..\_build\arm64\Release\SimpleMathComponent\bin\SimpleMathComponent\SimpleMathComponent.dll" target="runtimes\win10-arm64\native\SimpleMathComponent.dll" />--> </files> </package>
注
コンポーネントの実装アセンブリであるSimpleMathComponent.dllは、アーキテクチャ固有です。 他のプラットフォーム (x86 や Arm64 など) をサポートしている場合は、まず目的のプラットフォーム用 に SimpleMathComponent をビルドし、これらのアセンブリ ファイルを適切な RID 相対フォルダーに追加する必要があります。 プロジェクション アセンブリ SimpleMathProjection.dll と コンポーネント SimpleMathComponent.winmd はどちらもアーキテクチャに依存しません。
編集したファイルを保存して閉じます。
ソリューションをビルドしてプロジェクションと NuGet パッケージを生成する
ソリューションをビルドする前に、Visual Studio の [ビルド] の [構成マネージャー] の設定>確認してください。 このチュートリアルでは、ソリューションの 構成 を Release に、Platform を x64 に設定します。
この時点で、ソリューションをビルドできるようになりました。 ソリューション ノードを右クリックし、[ソリューションのビルド]を選択します。 これにより、最初に SimpleMathComponent プロジェクトがビルドされ、次に SimpleMathProjection プロジェクトがビルドされます。 コンポーネント WinMD と実装アセンブリ (SimpleMathComponent.winmd と SimpleMathComponent.dll)、プロジェクション ソース ファイル、およびプロジェクション アセンブリ (SimpleMathProjection.dll) はすべて 、_build 出力ディレクトリの下に生成されます。 また、生成された NuGet パッケージ SimpleMathComponent0.1.0-prerelease.nupkg を 、\SimpleMathProjection\nuget フォルダーの下に表示することもできます。
Von Bedeutung
上記のファイルのいずれかが生成されない場合は、2 回目にソリューションをビルドします。 リビルドする前に、ソリューションを閉じて再度開く必要がある場合もあります。
Visual Studio で .nupkg
が表示されるようにするために、ソリューションを閉じて再度開く必要があることがあります(または、[すべてのファイルを表示] を選択してから選択解除するだけです)。
C# .NET 6 コンソール アプリケーションで NuGet パッケージを参照する
.NET プロジェクトから SimpleMathComponent を使用するには、前のセクションで作成した SimpleMathComponent0.1.0-prerelease.nupkg NuGet パッケージへの参照を新しい .NET プロジェクトに追加するだけです。 次の手順では、別のソリューションで単純なコンソール アプリを作成してこれを行う方法を示します。
次の手順を使用して、C# コンソール アプリ プロジェクトを含む新しいソリューションを作成します (新しいソリューションでこのプロジェクトを作成すると、 SimpleMathComponent NuGet パッケージを個別に復元できます)。
Von Bedeutung
この新しい コンソール アプリ プロジェクトを
\CsWinRT\src\Samples\NetProjectionSample
フォルダー内に作成します。このプロジェクトは、 C#/WinRT プロジェクション サンプルのダウンロードまたは複製にあります。- Visual Studio の新しいインスタンスで、 File>New>Project を選択します。
- [ 新しいプロジェクトの作成 ] ダイアログ ボックスで、 コンソール アプリ プロジェクト テンプレートを検索します。 コンソール アプリ
呼び出す C# プロジェクト テンプレート (プレフィックスもサフィックスも付かない) を選択し、[次へ] クリック 。 Visual Studio 2019 を使用している場合、プロジェクト テンプレートは コンソール アプリケーションです。 - SampleConsoleApp
に新しいプロジェクトの名前を付け、その場所を SimpleMathComponent フォルダーと SimpleMathProjection フォルダーと同じ フォルダーに設定し、[次へ]をクリックします 。 - [ 追加情報 ] ページ で、[.NET 6.0 (長期サポート)]、[ 作成] の順に選択します。
ソリューション エクスプローラーで SampleConsoleApp ノードをダブルクリックして SampleConsoleApp.csproj プロジェクト ファイルを開き、次の一覧に示すように
TargetFramework
プロパティとPlatform
プロパティを編集します。Platform
要素がない場合は追加します。<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework> <Platform>x64</Platform> </PropertyGroup>
SampleConsoleApp.csproj プロジェクト ファイルがまだ開いているので、次に SampleConsoleApp プロジェクトに SimpleMathComponent NuGet パッケージへの参照を追加します。 プロジェクトのビルド時に SimpleMathComponent NuGet を復元するには、コンポーネント ソリューション内の
RestoreSources
フォルダーへのパスと共に プロパティを使用できます。 次の構成をコピーし、 SampleConsoleApp.csproj (Project
要素内) に貼り付けます。<PropertyGroup> <RestoreSources> https://api.nuget.org/v3/index.json; ../SimpleMathProjection/nuget </RestoreSources> </PropertyGroup> <ItemGroup> <PackageReference Include="SimpleMathComponent" Version="0.1.0-prerelease" /> </ItemGroup>
Von Bedeutung
上記の
RestoreSources
パッケージの パスは、../SimpleMathProjection/nuget
に設定されています。 SimpleMathComponent プロジェクトと SampleConsoleApp プロジェクトの両方が同じフォルダー (この場合はNetProjectionSample
フォルダー) に含まれるように、このチュートリアルの手順に従った場合、このパスは正しいです。 別の作業を行った場合は、それに応じてそのパスを調整する必要があります。 または、 ローカル NuGet パッケージ フィードを ソリューションに追加することもできます。Program.cs ファイルを編集して、SimpleMathComponent によって提供される機能を使用します。
var x = new SimpleMathComponent.SimpleMath(); Console.WriteLine("Adding 5.5 + 6.5 ..."); Console.WriteLine(x.add(5.5, 6.5).ToString());
編集したファイルを保存して閉じ、コンソール アプリをビルドして実行します。 次の出力が表示されます。
既知の問題
- プロジェクション プロジェクトをビルドするときに、次のようなエラーが表示されることがあります。 エラー MSB3271ビルド中のプロジェクトのプロセッサ アーキテクチャ "MSIL" と、実装ファイルのプロセッサ アーキテクチャ "x86" が一致していません。\SimpleMathComponent.dll" for "..\SimpleMathComponent.winmd"。この不一致により、ランタイム エラーが発生する可能性があります。プロジェクトと実装ファイルの間でプロセッサ アーキテクチャを調整するように、Configuration Manager を使用してプロジェクトのターゲット プロセッサ アーキテクチャを変更することを検討するか、プロジェクトの対象プロセッサ アーキテクチャに一致するプロセッサ アーキテクチャを持つ実装ファイルで winmd ファイルを選択してください。 このエラーを回避するには、C# ライブラリ プロジェクト ファイルに次のプロパティを追加します。
<PropertyGroup> <!-- Workaround for MSB3271 error on processor architecture mismatch --> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup>
その他の考慮事項
このトピックで作成する方法を示した C# プロジェクション (または相互運用) アセンブリは非常に単純です。他のコンポーネントへの依存関係はありません。 ただし、Windows App SDK 型への参照を持つ C++/WinRT コンポーネントの C# プロジェクションを生成するには、プロジェクション プロジェクトで Windows App SDK NuGet パッケージへの参照を追加する必要があります。 このような参照がない場合は、"Type <T> could not found" などのエラーが表示されます。
このトピックで行うもう 1 つの操作は、プロジェクションを NuGet パッケージとして配布することです。 その は現在 必要です。
リソース
Windows developer