C#/WinRT

C#/WinRT は、C# 言語に対する Windows ランタイム (WinRT) プロジェクション サポートを提供する NuGet パッケージのツールキットです。 プロジェクション アセンブリは、ターゲット言語に対して自然で使い慣れた方法での WinRT API のプログラミングを可能にする、相互運用機能アセンブリです。 C#/WinRT プロジェクションは、C# と WinRT インターフェイス間の相互運用の詳細を隠し、多くの WinRT 型と、文字列、URI、共通値型、およびジェネリック コレクションなど、適切な .NET の同等物との間のマッピングを提供します。

C#/WinRT では現在、.NET でターゲット フレームワーク モニカー (TFM) を使うことによって WinRT API を使用するためのサポートを提供しています。 特定の Windows SDK バージョンで TFM を設定すると、C#/WinRT によって生成される Windows SDK のプロジェクション アセンブリおよびランタイム アセンブリへの参照が追加されます。

C#/WinRT NuGet パッケージを使用すると、.NET コンシューマー用に独自の WinRT 相互運用機能アセンブリを作成して参照することができます。 最新バージョンの C#/WinRT には、C# での WinRT 型の作成のプレビューも用意されています。

詳細については、C#/WinRT GitHub リポジトリに関するページを参照してください。

C#/WinRT の動機

.NET (以前の .NET Core) は、デバイス、クラウド、IoT のアプリケーションを構築するために使用できる、オープンソースのクロスプラットフォーム ランタイムです。

以前のバージョンの .NET Framework と .NET Core には、Windows 固有のテクノロジである WinRT に関する知識が組み込まれていました。 .NET 6 以降の移植性と効率性の目標をサポートするために、.NET コンパイラとランタイムから WinRT プロジェクションのサポートを解除し、C# または WinRT のツールキットに移動しました (WinRT の組み込みサポートの .NET からの削除に関する記事を参照してください)。 C#/WinRT の目標は、以前のバージョンの C# コンパイラおよび .NET ランタイムで提供されている組み込みの WinRT サポートと同等の機能を提供することです。 詳細については、「Windows ランタイム型の .NET マッピング」を参照してください。

C#/WinRT では、WinUI 3 を含む、Windows App SDK のコンポーネントもサポートされています。 Windows App SDK により、ネイティブの Microsoft UI コントロールやその他のネイティブのコンポーネントがオペレーティング システムから取り出されます。 これにより、アプリ開発者は、Windows 10 バージョン1809 以降のリリースで最新のコントロールとコンポーネントを使用できます。

最後に、C#/WinRT は一般的なツールキットであり、 C# コンパイラまたは .NET ランタイムで WinRT の組み込みサポートが使用できない、他のシナリオをサポートすることを目的としています。

新着情報

最新の C#/WinRT リリースは、GitHub リポジトリのリリース ノート ページにあります。

使用

C#/WinRT NuGet パッケージを使用して、WinRT コンポーネントから C# プロジェクション (相互運用機能アセンブとも呼ばれます) を生成することも、C#/WinRT コンポーネントを作成することもできます。 C#/WinRT の使用シナリオの詳細については、リポジトリの使用ガイドを参照してください。

相互運用機能アセンブリを生成して配布する

WinRT API は、Windows メタデータ (WinMD) ファイルに定義されます。 C#/WinRT NuGet パッケージ (Microsoft.Windows.CsWinRT) に含まれる C#/WinRT コンパイラ、cswinrt.exe を使用すると、WinMD ファイルの処理や .NET C# コードの生成を行えます。 C#/WinRT では、これらのソース ファイルが相互運用機能アセンブリにコンパイルされます。これは、C++/WinRT によって C++ 言語プロジェクションのヘッダーが生成される方法と同様です。 その後、C#/WinRT 相互運用機能アセンブリを、参照する .NET アプリケーション用の実装アセンブリと共に (通常、NuGet パッケージとして) 配布できます。

相互運用機能アセンブリを生成して配布する方法の詳細については、「C++/WinRT コンポーネントから C# プロジェクションを生成し、.NET アプリ用の NuGet として配布する」を参照してください。

相互運用機能アセンブリを参照する

通常、C#/WinRT 相互運用機能アセンブリは、アプリケーション プロジェクトによって参照されます。 ただし、それらは中間相互運用機能アセンブリによっても参照される場合があります。 たとえば、WinUI 相互運用機能アセンブリは Windows SDK 相互運用機能アセンブリを参照します。

公式の相互運用機能アセンブリを含めずにサードパーティの WinRT コンポーネントを配布する場合、アプリケーション プロジェクトでは、相互運用機能アセンブリの生成手順に従って、独自のプライベート プロジェクション ソースを生成することができます。 この方法は、プロセス内に同じ型の競合するプロジェクションを生成する可能性があるため、推奨されません。 NuGet のパッケージングは、セマンティックのバージョン管理スキームに従って、これを防ぐように設計されています。 公式のサードパーティ製相互運用機能アセンブリをお勧めします。

WinRT 型の Embedded サポート (プレビュー)

C#/WinRT バージョン1.4.1 以降では、.NET と .NET Standard 2.0 の両方の Windows SDK プロジェクションとランタイムソースをライブラリまたはアプリの出力に埋め込むためのサポートが含まれています。 これは、Windows SDK 型の使用が自己完結している場合に便利です。 Embedded サポートによって、WinRT.Runtime.dll および Microsoft.Windows.SDK.NET.dll での依存関係が削除されるため、ライブラリまたはアプリの出力サイズが削減されます。 また、ライブラリ開発者は、ダウンレベルのサポートを提供することができ、マルチターゲットも不要になります。

詳細については、リポジトリにある C#/WinRT Embedded のドキュメントを参照してください。

WinRT 型のアクティブ化

C#/WinRT は、オペレーティング システムでホストされている WinRT 型、および Win2D などのサードパーティ コンポーネントのアクティブ化をサポートしています。 デスクトップ アプリケーションでのサードパーティ コンポーネントのアクティブ化に関するサポートは、Windows 10 バージョン 1903 以降で利用可能な登録無料の WinRT のアクティブ化を使用して有効化されます。 ネイティブの C++ コンポーネントでは、プロジェクト プロパティまたは .vcxproj ファイルを使用して、Windows Desktop Compatible プロパティを True に設定する必要があります。これは、Microsoft.VCLibs.Desktop バイナリを参照して、使用するアプリに転送するために必要です。 そうしないと、コンポーネントが UWP アプリのみをターゲットとした場合に、アプリを使用することによって VCRT Forwarders パッケージが必要になります。

Windows が前述の型のアクティブ化に失敗した場合、C#/WinRT にはアクティブ化のフォールバック パスも用意されています。 この場合、C#/WinRT は、完全修飾型名に基づき、要素を段階的に削除して、ネイティブ実装 DLL を見つけようとします。 たとえば、フォールバック ロジックは、次のモジュールから順番に Contoso.Controls.Wiget 型のアクティブ化を試行します。

  1. Contoso.Controls.Widget.dll
  2. Contoso.Controls.dll
  3. Contoso.dll

C#/WinRT は、LoadLibrary 代替検索順序を使用して実装 DLL を見つけます。 このフォールバック動作に依存するアプリは、アプリ モジュールと共に実装 DLL をパッケージする必要があります。

一般的なエラーとトラブルシューティング

  • エラー:"Windows メタデータが指定されていないか、検出されません。"

    Windows メタデータを指定するには、<CsWinRTWindowsMetadata> プロジェクト プロパティを使用します。次に例を示します。

    <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
    

    C#/WinRT バージョン 1.2.1 以降では、このプロパティの既定値は TargetPlatformVersion です。これは、TargetFramework プロパティで指定された Windows SDK バージョンから派生します。

  • エラー CS0246:'Windows' という名前の型または名前空間が見つかりませんでした (using ディレクティブまたはアセンブリ参照が不足しています)

    このエラーに対処するには、特定の Windows バージョンを対象とするように <TargetFramework> プロパティを編集します。次に例を示します。

    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    

    <TargetFramework> プロパティの指定の詳細については、Windows ランタイム API の呼び出しに関するドキュメントを参照してください。

  • ComImport 属性を持つインターフェイスにキャストする場合の System.InvalidCastException

    ComImport 属性を持つインターフェイスにオブジェクトをキャストする場合、明示的なキャスト式を使用する代わりに、.As<> 演算子を使用する必要があります。 次に例を示します。

    someObject.As<SomeComImportInterface>
    

    詳細については、「COM 相互運用機能ガイド」を参照してください。

  • System.Runtime.InteropServices.COMException: クラスが登録されていません (0x80040154 (REGDB_E_CLASSNOTREG))

    • C#/WinRT プロジェクションを C++/WinRT コンポーネントから使用したときに、この例外が表示された場合は、プロジェクト プロパティまたは .vcxproj ファイルを使用して、コンポーネントで Windows Desktop Compatible プロパティが True に設定されていることを確認してください。

.NET SDK のバージョン管理エラー

そのすべての依存関係より以前のバージョンの .NET SDK を使用してビルドされたプロジェクトで、次のエラーまたは警告が発生する可能性があります。

エラーまたは警告のメッセージ 理由
警告 MSB3277: Found conflicts between different versions of WinRT.Runtime or Microsoft.Windows.SDK.NET that could not be resolved. (解決できなかった異なるバージョンの WinRT.Runtime または Microsoft.Windows.SDK.NET 間に競合が見つかりました。) This build warning occurs when referencing a library that exposes Windows SDK types on its API surface. (このビルド警告は、その API サーフェスに Windows SDK 型が公開されるライブラリを参照するときに発生します。)
エラー CS1705:Assembly 'AssemblyName1' uses 'TypeName' which has a higher version than referenced assembly 'AssemblyName2' (アセンブリ 'AssemblyName1' は、参照されるアセンブリ 'AssemblyName2' よりも新しいバージョンを持つ 'TypeName' を使用します) このビルド コンパイラ エラーは、ライブラリ内の公開された Windows SDK 型を参照および使用するときに発生します。
System.IO.FileLoadException このランタイム エラーは、Windows SDK 型が公開されないライブラリで特定の API を呼び出すと発生する可能性があります。

これらのエラーを修正するには、.NET SDK を最新バージョンに更新します。 これにより、お使いのアプリケーションで使用されるランタイムおよび Windows SDK アセンブリのバージョンとすべての依存関係との互換性が確実に保たれます。 これらのエラーは、.NET SDK への早期サービスまたは機能更新プログラムの適用で発生する可能性があります。これは、ランタイムの修正に、アセンブリのバージョンに対する更新プログラムが必要になる場合があるためです。

既知の問題

既知の問題と破壊的変更については、C#/WinRT の GitHub リポジトリを参照してください。

C#/WinRT NuGet パッケージ、cswinrt.exe コンパイラ、または生成されたプロジェクション ソースで機能上の問題が発生した場合は、C#/WinRT の問題のページから問題を送信してください。

その他の資料