Windows アプリの相互運用アプローチを選択する

Windowsデスクトップ アプリ (WinUI 3、WPF、WinForms、コンソール) では、マネージド フレームワークの外部で API を呼び出す必要がある場合があります。 このページは、それがいつ発生するかを理解し、適切な手法を選択するのに役立ちます。

2 つの API サーフェス、2 つの相互運用パターン

Windowsは、次の 2 つの主要な API サーフェスを介して機能を公開します。

  • Win32 API — システム DLL (user32.dllkernel32.dllshell32.dllなど) からエクスポートされる従来の C スタイルの関数。 これらは、ウィンドウ管理、ファイル I/O、プロセス制御、ハードウェア アクセスなどの低レベルの操作を対象としています。 これらは、Windowsの最も古いバージョンから存在しており、同等の管理を持たない多くの OS 機能にアクセスする方法のままです。

  • Windows ランタイム (WinRT) API — Windows 8で導入された最新のオブジェクト指向 API サーフェス (Windows.* 以降の名前空間)。 WinRT API には、通知、メディア キャプチャ、Bluetooth、位置情報などの領域が含まれます。 ほとんどの WinRT API は、特別な手間をかけずに.NETから直接アクセスできますが、デスクトップ アプリに制限がある場合や、ウィンドウ ハンドル (HWND) を機能させる必要があるものもあります。

相互運用性に遭遇するタイミング

通常、アプリ フレームワークが特定の OS 機能を直接公開しない場合は、相互運用が必要です。 一般的なシナリオは次のとおりです。

シナリオ どの API サーフェス Example
タイトル バーまたはウィンドウの配置をカスタマイズする Win32 SetWindowPosDwmExtendFrameIntoClientArea
ウィンドウを "常に上" に設定するか、Z オーダーを制御する Win32 SetWindowPosHWND_TOPMOST
WinUI 3 からファイル ピッカーまたは共有ダイアログを表示する WinRT (HWND が必要) FileOpenPickerInitializeWithWindow
システム メモリまたはパフォーマンス カウンターの読み取り Win32 GlobalMemoryStatusExQueryPerformanceCounter
グローバル ホットキーを登録する Win32 RegisterHotKey
トースト通知を送信する (パッケージ化されていないアプリ) WinRT (App SDK を使用) AppNotificationManager

いずれの場合も、通常の C# コードを記述しますが、相互運用レイヤーを介してWindowsを呼び出します。 以下のトピックでは、各アプローチについて説明します。

意思決定ガイド

…する必要があります 推奨される方法 トピック
C から Win32 API (user32、kernel32、shell32 など) を呼び出す# CsWin32 ソース ジェネレーター (タイプ セーフ、手書き署名なし) を使用する C# から Win32 API を呼び出す (CsWin32)
ウィンドウ ハンドル (ピッカー、ダイアログ、共有 UI) を使用して WinRT オブジェクトを初期化する .NET WinRT COM 相互運用機能クラス (InitializeWithWindowWindowNativeなど) を使用する .NET アプリから相互運用 API を呼び出します
WinRT API が デスクトップ (UWP 以外) アプリで動作するかどうかを確認する 制限事項と代替手段の一覧を参照する デスクトップ アプリでサポートされていない WinRT API
Win32 呼び出しを使用してウィンドウをカスタマイズする完全な WinUI 3 の例を参照してください エンド ツー エンドのチュートリアルに従う チュートリアル: WinUI 3 アプリと Win32 相互運用機能

クイック フローチャート

  1. API は Windows.* WinRT 名前空間にありますか?

  2. Win32/ネイティブ API (Windows SDK ヘッダーで定義) ですか?

    • はい → CsWin32 を使用して、タイプ セーフな P/Invoke バインドを生成します。
    • no → COM インターフェイスまたはサード パーティのネイティブ ライブラリである可能性があります。 一般的な P/Invoke ガイダンスについては.NETネイティブ コードとの相互運用を参照してください。