リモート アプリ サービスとの通信

URI を使ってリモート デバイスでアプリを起動するのに加えて、リモート デバイスでもアプリ サービスを実行して通信できます。 どの Windows ベースのデバイスでも、クライアント デバイス、またはホスト デバイスのいずれかとして使うことができます。 これにより、アプリをフォアグラウンドにしなくても、接続されているデバイスとやり取りする方法がほぼ無限になります。

ホスト デバイスでアプリ サービスをセットアップする

リモート デバイスでアプリ サービスを実行するには、アプリ サービスのプロバイダーが既にそのデバイスにインストールされている必要があります。 このガイドでは、ユニバーサル Windows アプリ サンプルのリポジトリで入手可能な乱数ジェネレーター アプリ サービスの CSharp バージョンを使います。 独自のアプリ サービスを記述する方法については、「アプリ サービスの作成と利用」を参照してください。

既製のアプリ サービスを使うか独自のアプリ サービスを記述するかにかかわらず、リモート システムとの互換性を確保するにはいくらかの編集を行う必要があります。 Visual Studio で、アプリ サービス プロバイダーのプロジェクト (サンプルでは「AppServicesProvider」と呼ばれます) に移動し、その Package.appxmanifest ファイルを選びます。 右クリックして [コードの表示] を選び、ファイルの全内容を表示します。 メインの Application 要素の内部に Extensions 要素を作成します (または、既にある場合はそれを見つけます)。 次に、Extension を作成して、プロジェクトをアプリ サービスとして定義し、その親プロジェクトを参照します。

...
<Extensions>
    <uap:Extension Category="windows.appService" EntryPoint="RandomNumberService.RandomNumberGeneratorTask">
        <uap3:AppService Name="com.microsoft.randomnumbergenerator"/>
    </uap:Extension>
</Extensions>
...

AppService 要素の後に、SupportsRemoteSystems 属性を追加します。

...
<uap3:AppService Name="com.microsoft.randomnumbergenerator" SupportsRemoteSystems="true"/>
...

この uap3 名前空間で要素を使用するために、マニフェスト ファイルの先頭に名前空間定義を追加する必要があります (まだそこにない場合)。

<?xml version="1.0" encoding="utf-8"?>
<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3">
  ...
</Package>

次に、アプリ サービス プロバイダー プロジェクトをビルドし、ホスト デバイスにデプロイします。

クライアント デバイスからアプリ サービスをターゲットにする

呼び出すリモート アプリ サービスの元となるデバイスには、リモート システム機能を備えたアプリが必要です。 これは、ホスト デバイスでアプリ サービスを提供する同じアプリに追加するか (この場合、両方のデバイスに同じアプリをインストールします)、完全に別のアプリに実装することができます。

このセクションのコードをそのまま実行するには、次の using ステートメントが必要です。

using Windows.ApplicationModel.AppService;
using Windows.System.RemoteSystems;

まず、アプリ サービスをローカルで呼び出すのと同じように AppServiceConnection オブジェクトをインスタンス化する必要があります。 このプロセスについては、「アプリ サービスの作成と利用」で詳しく説明します。 この例では、ターゲットにアプリ サービスは乱数ジェネレーター サービスです。

注意

次のメソッドを呼び出すコード内で、何らかの方法で RemoteSystem オブジェクトが既に取得されていることを前提としています。 これをセットアップする方法については、「リモート アプリの起動」をご覧ください。

// This method returns an open connection to a particular app service on a remote system.
// param "remotesys" is a RemoteSystem object representing the device to connect to.
private async void openRemoteConnectionAsync(RemoteSystem remotesys)
{
    // Set up a new app service connection. The app service name and package family name that
    // are used here correspond to the AppServices UWP sample.
    AppServiceConnection connection = new AppServiceConnection
    {
        AppServiceName = "com.microsoft.randomnumbergenerator",
        PackageFamilyName = "Microsoft.SDKSamples.AppServicesProvider.CS_8wekyb3d8bbwe"
    };

次に、目的のリモート デバイスに RemoteSystemConnectionRequest オブジェクトが作成されます。 これは、そのサービスに対して AppServiceConnection を開くために使われます。 次の例では、簡単にするためにエラー処理とレポートが大幅に簡略化されている点に注意してください。

// a valid RemoteSystem object is needed before going any further
if (remotesys == null)
{
    return;
}

// Create a remote system connection request for the given remote device
RemoteSystemConnectionRequest connectionRequest = new RemoteSystemConnectionRequest(remotesys);

// "open" the AppServiceConnection using the remote request
AppServiceConnectionStatus status = await connection.OpenRemoteAsync(connectionRequest);

// only continue if the connection opened successfully
if (status != AppServiceConnectionStatus.Success)
{
    return;
}

現時点では、リモート コンピューター上のアプリ サービスへの接続が開かれている必要があります。

リモート接続経由でサービス固有のメッセージをやり取りする

ここでは、ValueSet オブジェクトの形式を使ってサービスとの間でメッセージを送受信できます (詳しくは「アプリ サービスの作成と利用」をご覧ください)。 乱数ジェネレーター サービスは、キー "minvalue""maxvalue" と共に 2 つの整数を入力として取得し、その範囲内の整数をランダムに選んで、キー "Result" と共に呼び出し元プロセスに返します。

    // create the command input
    ValueSet inputs = new ValueSet();

    // min_value and max_value vars are obtained somewhere else in the program
    inputs.Add("minvalue", min_value);
    inputs.Add("maxvalue", max_value);

    // send input and receive output in a variable
    AppServiceResponse response = await connection.SendMessageAsync(inputs);

    string result = "";
    // check that the service successfully received and processed the message
    if (response.Status == AppServiceResponseStatus.Success)
    {
        // Get the data that the service returned:
        result = response.Message["Result"] as string;
    }
}

ここでは、ターゲットとなるホスト デバイス上のアプリ サービスに接続して、そのデバイスで操作を実行し、応答でクライアント デバイスへのデータを受信しました。

接続されるアプリやデバイス (Project Rome) の概要
リモート アプリの起動
App Service の作成と利用
リモート システムの API リファレンス
リモート システムのサンプル