Запуск приложения на удаленном устройстве

В этой статье объясняется, как запустить приложение для Windows на удаленном устройстве.

Начиная с Windows 10 версии 1607, приложение UWP может запускать приложение UWP или классическое приложение для Windows удаленно на другом устройстве, которое также работает с Windows 10 версии 1607 или выше, при условии что вход на обоих устройствах выполнен с той же учетной записью Майкрософт (MSA). Это самый простой вариант использования Project Rome.

Функция удаленного запуска создает удобную пользовательскую среду для выполнения задач, и пользователь может начать выполнять задачу на одном устройстве и завершить на другом. Например, если пользователь слушает музыку на телефоне в своей машине, придя домой, он или она может продолжить воспроизведение на Xbox One. Удаленный запуск позволяет приложениям передавать контекстные данные в запускаемое удаленное приложение и продолжать работу в нем.

Предварительная настройка

Добавление возможности remoteSystem

Чтобы приложение могло запускать другое приложение на удаленном устройстве, вам потребуется добавить возможность remoteSystem в манифест пакета приложений. Вы можете использовать конструктор манифеста пакета, чтобы добавить его, выбрав Удаленная система на вкладке Возможности или вручную добавить следующую строку в файл Package.appxmanifest проекта.

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

Возможность совместной работы на разных устройствах

Кроме того на клиентском устройстве должно быть разрешено использование на нескольких устройствах. Этот параметр, доступ к которому можно получить в разделе Параметры: Система>Общие возможности>Передача между устройствами, включен по умолчанию.

страница параметров общих возможностей

Поиск удаленного устройства

Сначала вам потребуется найти устройство, к которому нужно подключиться. В статье Обнаружение удаленных устройств подробно описано, как это сделать. Мы воспользуемся простым способом, не прибегая к фильтрации по типу устройства или подключения. Мы создадим наблюдатель удаленных систем для поиска удаленных устройств и создадим обработчики событий, которые возникают при удалении или обнаружении устройств. Так мы получим коллекцию удаленных устройств.

В коде из этих примеров требуется, чтобы в ваших файлах класса имелся оператор using Windows.System.RemoteSystems.

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(). Проверьте полученное значение и убедитесь, что у вашего приложения есть разрешение на доступ к удаленным устройствам. Эта проверка может не удаться, если вы не добавили возможность remoteSystem в приложение.

Обработчики событий наблюдателя систем вызываются при обнаружении устройства, к которому можно подключиться, или прекращении доступа к нему. Мы будем использовать эти обработчики событий для ведения актуального списка устройств, к которым можно подключиться.

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);
}

Мы будет отслеживать устройства по идентификатору удаленной системы с помощью словаря. Для содержания исчисляемого списка устройств используется класс ObservableCollection. Класс ObservableCollection также упрощает привязку списка устройств к пользовательскому интерфейсу, но мы не будем этого делать в нашем примере.

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

Добавьте вызов метода BuildDeviceList() в код запуска приложения перед запуском удаленного приложения.

Запуск приложения на удаленном устройстве

Запустите приложение удаленно, указав устройство, к которому требуется подключиться, в API RemoteLauncher.LaunchUriAsync. Для этого метода существует три перегрузки. В самой простой из них, используемой в этом примере, указывается универсальный код ресурса (URI), с помощью которого активируется приложение на удаленном устройстве. В этом примере с помощью URI открывается приложение "Карты" на удаленной системе с трехмерным представлением башни Спейс-Нидл.

Другие перегрузки RemoteLauncher.LaunchUriAsync позволяют указывать такие параметры, как URI веб-сайта для проверки невозможности запуска подходящего приложения, способного обработать этот URI, на удаленном устройстве, и необязательный список имен семейства пакетов, который можно использовать для запуска этого URI на удаленном устройстве. Вы также можете предоставить данные в виде пар "ключ-значение". Вы можете передать данные приложению, которое запускается, чтобы предоставить контекст для удаленного приложения, например название песни, которую требуется воспроизвести, и текущее расположение воспроизведения при передаче воспроизведения с одного устройства на другое.

В практических сценариях можно предоставить пользовательский интерфейс для выбора целевого устройства. Однако для упрощения этого примера мы воспользуемся только первым удаленным устройством из списка.

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"));
}

Объект RemoteLaunchUriStatus, возвращаемый методом RemoteLauncher.LaunchUriAsync(), содержит сведения об успешном удаленном запуске или причинах его сбоя.

Справочник по API удаленных систем
Обзор подключенных приложений и устройств (Project Rome)
Обнаружение удаленных устройств
Пример удаленных систем демонстрирует, как обнаружить удаленную систему, запустить приложение в удаленной системе и использовать службы приложений для передачи сообщений между приложениями, работающими в двух системах.