リモート デバイスでのアプリの起動Launch an app on a remote device

この記事では、Windows アプリをリモート デバイスで起動する方法について説明します。This article explains how to launch a Windows app on a remote device.

Windows 10 Version 1607 以降で実行される UWP アプリは、同じく Windows Version 1607 を実行し、同じ Microsoft アカウント (MSA) にサインオンしている別のデバイスの UWP アプリまたは Windows デスクトップ アプリケーションをリモートで起動できます。Starting in Windows 10, version 1607, a UWP app can launch a UWP app or Windows desktop application remotely on another device that is also running Windows 10, version 1607 or later, provided that both devices are signed on with the same Microsoft Account (MSA). これは Project Rome の最も簡単な使用例です。This is the simplest use case of Project Rome.

このリモート起動機能を使うと、ユーザーが 1 台のデバイスでタスクを開始し、別のデバイスでそのタスクを完了するといった、タスク指向のユーザー エクスペリエンスが実現します。The remote launch feature enables task-oriented user experiences; a user can start a task on one device and finish it on another. たとえば、車を運転しながらスマートフォンで音楽を聴き、自宅に着いた後は、機器を Xbox One に切り替えて同じ音楽を引き続き再生することができます。For example, if the user is listening to music on their phone in their car, they could then hand playback functionality over to their Xbox One when they arrive at home. リモート起動では、中断した箇所からタスクを続行できるように、起動するリモート アプリにコンテキスト データを渡します。Remote launch allows apps to pass contextual data to the remote app being launched, in order to pick up where the task was left off.

準備段階のセットアップPreliminary setup

remoteSystem 機能を追加するAdd the remoteSystem capability

アプリでリモート デバイスのアプリを起動するには、remoteSystem 機能をアプリ パッケージ マニフェストに追加する必要があります。In order for your app to launch an app on a remote device, you must add the remoteSystem capability to your app package manifest. パッケージマニフェストデザイナーを使用して、[機能] タブの [リモートシステム] を選択することによって追加できます。また、プロジェクトの_package.appxmanifest_ファイルに次の行を手動で追加することもできます。You can use the package manifest designer to add it by selecting Remote System on the Capabilities tab, or you can manually add the following line to your project's Package.appxmanifest file.

<Capabilities>
   <uap3:Capability Name="remoteSystem"/>
</Capabilities>

クロスデバイス共有を実現Enable cross-device sharing

さらに、クライアントデバイスは、デバイス間の共有を許可するように設定する必要があります。Additionally, the client device must be set to allow cross-device sharing. この設定には [設定] : [システム] > [共有エクスペリエンス] > [デバイス間で共有します] でアクセスできます。既定で有効になっています。This setting, which is accessed in Settings: System > Shared experiences > Share across devices, is enabled by default.

[共有エクスペリエンス] 設定ページ

リモート デバイスを見つけるFind a remote device

最初に、接続するデバイスを見つける必要があります。You must first find the device that you want to connect with. この方法については、「リモート デバイスの検出」で詳しく説明されています。Discover remote devices discusses how to do this in detail. ここでは、デバイスまたは接続の種類によるフィルタリングを避けた、シンプルなアプローチを使います。We'll use a simple approach here that forgoes filtering by device or connectivity type. つまり、リモート デバイスを探すリモート システム ウォッチャーを作成し、デバイスが検出または削除されたときに発生するイベントのハンドラーを記述します。We will create a remote system watcher that looks for remote devices, and write handlers for the events that are raised when devices are discovered or removed. これにより、リモート デバイスのコレクションが提供されます。This will provide us with a collection of remote devices.

この例のコードでは、クラス ファイルに using Windows.System.RemoteSystems ステートメントがあることを利用としています。The code in these examples requires that you have a using Windows.System.RemoteSystems statement in your class file(s).

private async Task BuildDeviceList()
{
    RemoteSystemAccessStatus accessStatus = await RemoteSystem.RequestAccessAsync();

    if (accessStatus == RemoteSystemAccessStatus.Allowed)
    {
        m_remoteSystemWatcher = RemoteSystem.CreateWatcher();

        // Subscribing to the event raised when a new remote system is found by the watcher.
        m_remoteSystemWatcher.RemoteSystemAdded += RemoteSystemWatcher_RemoteSystemAdded;

        // Subscribing to the event raised when a previously found remote system is no longer available.
        m_remoteSystemWatcher.RemoteSystemRemoved += RemoteSystemWatcher_RemoteSystemRemoved;

        m_remoteSystemWatcher.Start();
    }
}

リモート起動を作成する前に、最初に RemoteSystem.RequestAccessAsync() を呼び出す必要があります。The first thing you must do before making a remote launch is call RemoteSystem.RequestAccessAsync(). 戻り値を確認して、お使いのアプリがリモート デバイスにアクセスする許可を持っていることを確認してください。Check the return value to make sure your app is allowed to access remote devices. このチェックが失敗する理由の 1 つは、アプリに remoteSystem 機能を追加していないことです。One reason this check could fail is if you haven't added the remoteSystem capability to your app.

システム ウォッチャーのイベント ハンドラーは、接続可能なデバイスが検出されたとき、または接続できなくなったときに呼び出されます。The system watcher event handlers are called when a device that we can connect with is discovered or is no longer available. これらのイベント ハンドラーを使用して、接続可能なデバイスの一覧を最新に保ちます。We will use these event handlers to keep an updated list of devices that we can connect to.

private void RemoteSystemWatcher_RemoteSystemRemoved(
    RemoteSystemWatcher sender, RemoteSystemRemovedEventArgs args)
{
    if ( m_deviceMap.ContainsKey(args.RemoteSystemId))
    {
        m_deviceList.Remove(m_deviceMap[args.RemoteSystemId]);
        m_deviceMap.Remove(args.RemoteSystemId);
    }
}

private void RemoteSystemWatcher_RemoteSystemAdded(
    RemoteSystemWatcher sender, RemoteSystemAddedEventArgs args)
{
    m_deviceList.Add(args.RemoteSystem);
    m_deviceMap.Add(args.RemoteSystem.Id, args.RemoteSystem);
}

Dictionary を使って、リモート システム ID によってデバイスを追跡します。We will track the devices by remote system ID using a Dictionary. ObservableCollection を使って、列挙可能なデバイスの一覧を保持します。An ObservableCollection is used to hold the list of devices that we can enumerate. ObservableCollection ではデバイスの一覧を UI にバインドすることも簡単にできますが、この例では行いません。An ObservableCollection also makes it easy to bind the list of devices to UI, though we won't do that in this example.

private RemoteSystemWatcher m_remoteSystemWatcher;
private ObservableCollection<RemoteSystem> m_deviceList = new ObservableCollection<RemoteSystem>();
private Dictionary<string, RemoteSystem> m_deviceMap = new Dictionary<string, RemoteSystem>();

リモート アプリの起動を試みる前に、アプリのスタートアップ コードに BuildDeviceList() への呼び出しを追加します。Add a call to BuildDeviceList() in your app startup code before you attempt to launch a remote app.

リモート デバイスでのアプリの起動Launch an app on a remote device

接続するデバイスを RemoteLauncher.LaunchUriAsync API に渡すことによって、アプリをリモートで起動します。Launch an app remotely by passing the device you wish to connect with to the RemoteLauncher.LaunchUriAsync API. このメソッドには 3 つのオーバーロードがあります。There are three overloads for this method. この例で示されている最も単純なオーバーロードでは、リモート デバイス上のアプリをアクティブ化する URI を指定します。The simplest, which this example demonstrates, specifies the URI that will activate the app on the remote device. この例では、URI によって、リモート コンピューター上のマップ アプリがスペース ニードルの 3D ビューで開かれます。In this example the URI opens the Maps app on the remote machine with a 3D view of the Space Needle.

その他の RemoteLauncher.LaunchUriAsync のオーバーロードでは、適切なアプリがリモート デバイスで起動できない場合に参照する Web サイトの URI などのオプションや、リモート デバイスでの URI の起動に使用できるパッケージ ファミリ名のオプションの一覧を指定できます。Other RemoteLauncher.LaunchUriAsync overloads allow you to specify options such as the URI of the web site to view if no appropriate app can be launched on the remote device, and an optional list of package family names that could be used to launch the URI on the remote device. キーと値のペアの形式でデータを提供することもできます。You can also provide data in the form of key/value pairs. 音楽の再生をデバイスから別のデバイスへと切り替えるとき、アクティブ化しているアプリにデータを渡して、再生する曲名や現在の再生位置などのコンテキストをリモート アプリに提供する場合があります。You might pass data to the app you are activating to provide context to the remote app, such as the name of the song to play and the current playback location when you hand off playback from one device to another.

実際には、使用するデバイスを選ぶための UI を表示するのが普通です。In practical scenarios, you might provide UI to select the device you want to target. しかしこの例では単純にするために、一覧の最初のリモート デバイスのみを使います。But to simplify this example, we'll just use the first remote device on the list.

if ( m_deviceList.Count > 0)
{
    RemoteSystem SelectedDevice = m_deviceList[0];
    RemoteLaunchUriStatus launchUriStatus = 
        await RemoteLauncher.LaunchUriAsync(
            new RemoteSystemConnectionRequest(SelectedDevice), 
            new Uri("bingmaps:?cp=47.6204~-122.3491&sty=3d&rad=200&pit=75&hdg=165"));
}

RemoteLauncher.LaunchUriAsync() から返される RemoteLaunchUriStatus オブジェクトは、リモートの起動が成功したかどうか、さらに、失敗した場合はその理由についての情報を提供します。The RemoteLaunchUriStatus object that is returned from RemoteLauncher.LaunchUriAsync() provides information about whether the remote launch succeeded, and if not, the reason why.

リモート システムの API リファレンスRemote Systems API reference
接続されているアプリとデバイス (プロジェクトローマ) の概要Connected apps and devices (Project Rome) overview
リモート デバイスの検出Discover remote devices
リモート システムのサンプルでは、リモート システムを検出する方法、リモート システムでアプリを起動する方法、アプリ サービスを使って 2 つのシステム上で実行しているアプリ間でメッセージを送信する方法が説明されています。Remote Systems sample demonstrates how to discover a remote system, launch an app on a remote system, and use app services to send messages between apps running on two systems.