プロセス間通信 (IPC)

このトピックでは、ユニバーサル Windows プラットフォーム (UWP) アプリケーションと Win32 アプリケーションの間でプロセス間通信 (IPC) を実行するさまざまな方法について説明します。

アプリ サービス

App services を使用すると、アプリケーションで、プリミティブ (Valueset) のプロパティ バッグを受け取って返すサービスをバックグラウンドで公開できます。 リッチ オブジェクトは、シリアル化されている場合に渡すことができます。

App service では、アウトプロセスをバックグラウンド タスクとして実行することも、インプロセスをフォアグラウンド アプリケーション内で実行することもできます。

App services は、ほぼリアルタイムの待機時間を必要としない、少量のデータを共有する場合に最適です。

COM

COM は、相互作用および通信を可能にするバイナリ ソフトウェア コンポーネントを作成するための分散オブジェクト指向システムです。 開発者は、COM を使用して、アプリケーションの再利用可能なソフトウェア コンポーネントとオートメーション レイヤーを作成します。 COM コンポーネントは、インプロセスまたはアウトプロセスである可能性があり、クライアントとサーバーのモデルを介して通信できます。 アウトプロセス COM サーバーは、オブジェクト間通信の手段として長い間使用されてきました。

runFullTrust 機能を使用するパッケージ アプリケーションでは、パッケージ マニフェストを使用して IPC 用のアウトプロセス COM サーバーを登録できます。 これは、パッケージ COM と呼ばれます。

ファイルシステム

BroadFileSystemAccess

パッケージ アプリケーションでは、broadFileSystemAccess 制限付き機能を宣言することにより、広範なファイルシステムを使用して IPC を実行できます。 この機能により、Windows.Storage API と xxxFromApp Win32 API は広範なファイルシステムにアクセスできるようになります。

既定では、パッケージ アプリケーションのファイルシステムを介した IPC は、このセクションで説明する他のメカニズムに限定されます。

PublisherCacheFolder

PublisherCacheFolder を使用すると、パッケージ アプリケーションでは、同じ発行元が他のパッケージと共有できるフォルダーをマニフェストで宣言できます。

共有ストレージ フォルダーには、次の要件と制限があります。

  • 共有ストレージ フォルダー内のデータはバックアップされず、ローミングもされません。
  • ユーザーは、共有ストレージ フォルダーの内容を消去できます。
  • 共有ストレージ フォルダーを使用して、異なる発行元のアプリケーション間でデータを共有することはできません。
  • 共有ストレージ フォルダーを使用して、異なるユーザー間でデータを共有することはできません。
  • 共有ストレージ フォルダーには、バージョン管理はありません。

複数のアプリケーションを発行し、それらの間でデータを共有するための簡単なメカニズムを探している場合、PublisherCacheFolder は単純なファイルシステムベースのオプションです。

SharedAccessStorageManager

SharedAccessStorageManager は、トークンを介して StorageFiles を共有するために、App services、プロトコルのアクティブ化 (たとえば、LaunchUriForResultsAsync) などと組み合わせて使用します。

FullTrustProcessLauncher

runFullTrust 機能を使用すると、パッケージ アプリケーションでは、同じパッケージ内で完全信頼のプロセスを起動することができます。

パッケージの制限が負担になるシナリオ、または IPC オプションがないシナリオの場合、アプリケーションでは、完全信頼のプロセスをプロキシとして使用して、システムとのインターフェイスを設定し、App services または適切にサポートされている他の IPC メカニズムを介して完全信頼のプロセス自体との IPC を実行できます。

LaunchUriForResultsAsync

LaunchUriForResultsAsync は、ProtocolForResults アクティブ化コントラクトを実装する他のパッケージ アプリケーションとの単純な (ValueSet) データ交換に使用されます。 通常はバックグラウンドで実行される App services とは異なり、ターゲット アプリケーションはフォアグラウンドで起動されます。

ファイルは、ValueSet を介して SharedStorageAccessManager トークンをアプリケーションに渡すことによって共有できます。

ループバック

ループバックは、localhost (ループバック アドレス) でリッスンしているネットワーク サーバーと通信するプロセスです。

セキュリティとネットワーク分離を維持するために、パッケージ アプリケーションでは既定で、IPC のループバック接続がブロックされます。 信頼されたパッケージ アプリケーション間のループバック接続は、機能マニフェストのプロパティを使用して有効にすることができます。

  • ループバック接続に参加するすべてのパッケージ アプリケーションでは、パッケージ マニフェストprivateNetworkClientServer 機能を宣言する必要があります。
  • パッケージ マニフェスト内で LoopbackAccessRules を宣言することにより、2 つのパッケージ アプリケーションがループバックを介して通信できるようになります。
    • 各アプリケーションでは、LoopbackAccessRules内の他のアプリケーションを一覧表示する必要があります。 クライアントでは、サーバーの "out" 規則を宣言し、サーバーでは、サポートされているクライアントの "in" 規則を宣言します。

Note

これらの規則でアプリケーションを識別するために必要なパッケージ ファミリー名は、開発時に Visual Studio のパッケージ マニフェスト エディターで、Microsoft Store 経由で公開されたアプリケーションのパートナー センターを介して、または既にインストールされているアプリケーションの Get-AppxPackage PowerShell コマンドを使用して見つけることができます。

パッケージ化されていないアプリケーションおよびサービスにはパッケージ ID がないため、LoopbackAccessRules で宣言することはできません。 CheckNetIsolation.exeを介して、パッケージ化されていないアプリケーションおよびサービスとループバック経由で接続するようにパッケージ アプリケーションを構成できますが、これは、マシンにローカル アクセスでき、管理者権限を持っているサイドロードまたはデバッグ シナリオでのみ可能です。

  • ループバック接続に参加するすべてのパッケージ アプリケーションでは、パッケージ マニフェストprivateNetworkClientServer 機能を宣言する必要があります。
  • パッケージ アプリケーションがパッケージ化されていないアプリケーションまたはサービスに接続されている場合は、CheckNetIsolation.exe LoopbackExempt -a -n=<PACKAGEFAMILYNAME> を実行して、パッケージ化されたアプリケーションのループバック除外対象を追加します。
  • パッケージ化されていないアプリケーションまたはサービスがパッケージ アプリケーションに接続されている場合は、CheckNetIsolation.exe LoopbackExempt -is -n=<PACKAGEFAMILYNAME> を実行して、パッケージ アプリケーションでインバウンド ループバック接続を受信できるようにします。
    • パッケージ アプリケーションが接続をリッスンしている間、CheckNetIsolation.exe が継続的に実行されている必要があります。
    • -is フラグは、Windows 10 バージョン 1607 (10.0、ビルド 14393) で導入されました。

Note

CheckNetIsolation.exe-n フラグに必要なパッケージ ファミリー名は、開発時に Visual Studio のパッケージ マニフェスト エディターで、Microsoft Store 経由で公開されたアプリケーションのパートナー センターを介して、または既にインストールされているアプリケーションの Get-AppxPackage PowerShell コマンドを使用して見つけることができます。

CheckNetIsolation.exe は、ネットワーク分離の問題のデバッグにも役立ちます。

パイプ

パイプを使用すると、パイプ サーバーと 1 つ以上のパイプ クライアントの間で簡単な通信を行うことができます。

匿名パイプ および 名前付きパイプは、次の制約付きでサポートされます。

  • 既定では、パッケージ アプリケーションの名前付きパイプは、プロセスが完全に信頼されている場合を除き、同じパッケージ内のプロセス間でのみサポートされます。
  • 名前付きパイプは、名前付きオブジェクトの共有に関するガイドラインに従ってパッケージ間で共有できます。
  • 名前付きパイプ (パッケージ化済みアプリケーションおよび未パッケージ化 アプリケーション) では、パイプ名に構文 \\.\pipe\LOCAL\ を使用する必要があります。

レジストリ

通常、IPC でのレジストリの使用は推奨されませんが、既存のコードではサポートされています。 パッケージ アプリケーションでは、アクセスするためのアクセス許可を持つレジストリ キーにのみアクセスできます。

通常、パッケージ化されたデスクトップ アプリケーション (「コードからの MSIX パッケージのビルド」を参照) では、レジストリの仮想化を利用して、グローバル レジストリの書き込みが MSIX パッケージ内のプライベート ハイブに含まれるようにします。 これにより、グローバル レジストリへの影響を最小限に抑えながらソース コードの互換性を確保できます。これは、同じパッケージ内にあるプロセス間の IPC に使用できます。 レジストリを使用する必要がある場合、グローバル レジストリを操作するよりも、このモデルを使用することをお勧めします。

RPC

RPC を使用すると、パッケージ アプリケーションが RPC エンドポイントの ACL と一致する適切な機能を備えている場合に、パッケージ アプリケーションを Win32 RPC エンドポイントに接続できます。

カスタム機能を使用すると、OEM および IHV では、任意の機能を定義し、それらと RPC エンドポイントとの ACL を行い、承認されたクライアント アプリケーションに対してそれらの機能を許可することができます。 完全なサンプル アプリケーションについては、CustomCapability サンプルを参照してください。

RPC エンドポイントを使用して、特定のパッケージ アプリケーションへの ACL を行い、カスタム機能の管理オーバーヘッドを必要とせずに、エンドポイントへのアクセスをそれらのアプリケーションのみに制限することもできます。 DeriveAppContainerSidFromAppContainerName API を使用すると、パッケージ ファミリー名から SID を取得し、CustomCapability サンプルで示すように、その SID と RPC エンドポイントの ACL を行うことができます。

共有メモリ

ファイル マッピング を使用すると、次の制約付きで、2 つ以上のプロセス間でファイルまたはメモリを共有できます。

  • 既定では、パッケージ アプリケーションのファイル マッピングは、プロセスが完全に信頼されている場合を除き、同じパッケージ内のプロセス間でのみサポートされます。
  • ファイル マッピングは、名前付きオブジェクトの共有に関するガイドラインに従ってパッケージ間で共有できます。

大量のデータを効率的に共有および操作するには、共有メモリを使用することをお勧めします。