Поделиться через


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

Основные API

Узнайте, как запустить приложение из другого приложения и обмениваться данными между ними. Это называется запуск приложения для получения результатов. В этом примере показано, как использовать LaunchUriForResultsAsync для запуска приложения для получения результатов.

Новые API связи между приложениями в Windows 10 позволяют приложениям Windows (и веб-приложениям Windows) запускать приложения и обмениваться данными и файлами. Это позволяет создавать mash-up решения из нескольких приложений. Используя эти новые API, сложные задачи, необходимые пользователю для использования нескольких приложений, теперь можно легко обрабатывать. Например, ваше приложение может запустить приложение социальной сети для выбора контакта или запустить приложение для получения оплаты.

Приложение, которое вы запускаете для получения результатов, будет называться «Запущенное приложение». Приложение, которое запускает приложение, будет называться вызывающим приложением. В этом примере вы напишете как вызывающее приложение, так и запущенное приложение.

Шаг 1. Регистрация протокола для обработки в приложении, которое будет запущено для получения результатов

В файле Package.appxmanifest запускаемого приложения добавьте расширение протокола в раздел <Application>. В этом примере используется вымышленный протокол с именем test-app2app.

Атрибут returnResults в расширении протокола принимает одно из следующих значений:

  • необязательный— приложение можно запустить с целью получения результатов с помощью метода LaunchUriForResultsAsync или без получения результатов с помощью LaunchUriAsync. При использовании необязательныхс запущенное приложение должно определить, было ли оно запущено для получения результатов. Это можно сделать, проверив аргумент события OnActivated. Если свойство аргумента IActivatedEventArgs.Kind возвращает значение ActivationKind.ProtocolForResultsили если тип аргумента события - ProtocolActivatedEventArgs, то приложение было запущено с помощью метода LaunchUriForResultsAsync.
  • всегда— приложение можно запустить только для результатов; другими словами, оно может реагировать только на LaunchUriForResultsAsync.
  • нет— приложение не может быть запущено, чтобы получить результаты; оно может реагировать только на LaunchUriAsync.

В этом примере расширения протокола приложение можно запустить только для результатов. Это упрощает логику внутри метода OnActivated , описанного ниже, поскольку мы должны обрабатывать лишь случай "запуск для получения результатов," а не другие случаи активации приложения.

<Applications>
   <Application ...>

     <Extensions>
       <uap:Extension Category="windows.protocol">
         <uap:Protocol Name="test-app2app" ReturnResults="always">
           <uap:DisplayName>Test app-2-app</uap:DisplayName>
         </uap:Protocol>
       </uap:Extension>
     </Extensions>

   </Application>
</Applications>

Шаг 2: Переопределите Application.OnActivated в приложении, из которого вы получите результаты.

Если этот метод еще не существует в запущенном приложении, создайте его в классе App, определенном в App.xaml.cs.

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

using Windows.ApplicationModel.Activation;
...
protected override void OnActivated(IActivatedEventArgs args)
{
    // Window management
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null)
    {
        rootFrame = new Frame();
        Window.Current.Content = rootFrame;
    }

    // Code specific to launch for results
    var protocolForResultsArgs = (ProtocolForResultsActivatedEventArgs)args;
    // Open the page that we created to handle activation for results.
    rootFrame.Navigate(typeof(LaunchedForResultsPage), protocolForResultsArgs);

    // Ensure the current window is active.
    Window.Current.Activate();
}
using namespace winrt::Windows::ApplicationModel::Activation;
...
protected override void OnActivated(IActivatedEventArgs args)
{
    // Window management
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }
    
    if (rootFrame == null)
    {
        rootFrame = Frame();
        Window::Current().Content(rootFrame);
    }

    // Code specific to launch for results
    auto protocolForResultsEventArgs{ args.as<ProtocolForResultsActivatedEventArgs>() };
    // Open the page that we created to handle activation for results.
    rootFrame.Navigate(xaml_typename<LaunchedForResultsPage>(), protocolForResultsArgs);

    // Ensure the current window is active.
    Window::Current().Activate();
}

Так как расширение протокола в файле Package.appxmanifest указывает ReturnResults как всегда, приведенный выше код может преобразовать непосредственно в ProtocolForResultsActivatedEventArgs с уверенностью в том, что только ProtocolForResultsActivatedEventArgs будут отправляться в OnActivated для этого приложения. Если ваше приложение может быть активировано способами, иными чем запуск для получения результатов, вы можете проверить, возвращает ли свойство IActivatedEventArgs.Kind значение ActivationKind.ProtocolForResults, чтобы определить, было ли приложение запущено для получения результатов.

Шаг 3. Добавление поля ProtocolForResultsOperation в приложение, которое вы запускаете для результатов

private Windows.System.ProtocolForResultsOperation _operation = null;
Windows::System::ProtocolForResultsOperation _operation = nullptr;

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

Шаг 4. Переопределите OnNavigatedTo() в приложении, которое вы запускаете для результатов

Переопределите метод OnNavigatedTo на странице, которую вы будете отображать при запуске приложения для отображения результатов. Если этот метод еще не существует, создайте его в классе для страницы, определенной в <имени страницы>.xaml.cs. Убедитесь, что в верхней части файла включено следующее утверждение с использованием.

using Windows.ApplicationModel.Activation
using namespace winrt::Windows::ApplicationModel::Activation;

Объект NavigationEventArgs в методе OnNavigatedTo содержит данные, передаваемые из вызывающего приложения. Данные могут не превышать 100 КБ и хранятся в объекте ValueSet.

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

using Windows.ApplicationModel.Activation;
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var protocolForResultsArgs = e.Parameter as ProtocolForResultsActivatedEventArgs;
    // Set the ProtocolForResultsOperation field.
    _operation = protocolForResultsArgs.ProtocolForResultsOperation;

    if (protocolForResultsArgs.Data.ContainsKey("TestData"))
    {
        string dataFromCaller = protocolForResultsArgs.Data["TestData"] as string;
    }
}
...
private Windows.System.ProtocolForResultsOperation _operation = null;
using namespace winrt::Windows::ApplicationModel::Activation;
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    auto protocolForResultsArgs = e.Parameter().try_as<ProtocolForResultsActivatedEventArgs>();
    // Set the ProtocolForResultsOperation field.
    _operation = protocolForResultsArgs.ProtocolForResultsOperation();

    if (protocolForResultsArgs.Data().HasKey("TestData"))
    {
        string dataFromCaller{ unbox_value<hstring>(protocolForResultsArgs.Data().Lookup("TestData")) };
    }
}
...
Windows::System::ProtocolForResultsOperation _operation = nullptr;

Шаг 5. Написание кода для возврата данных в вызывающее приложение

В запущенном приложении используйте ProtocolForResultsOperation для возврата данных в вызывающее приложение. В этом примере кода создается объект ValueSet, содержащий значение, возвращаемое вызывающему приложению. Затем поле ProtocolForResultsOperation используется для отправки значения вызывающему приложению.

    ValueSet result = new ValueSet();
    result["ReturnedData"] = "The returned result";
    _operation.ReportCompleted(result);
    ValueSet result;
    result.Insert("ReturnedData", "The returned result");
    _operation.ReportCompleted(result);

Шаг 6. Написание кода для запуска приложения для результатов и получение возвращаемых данных

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

using System.Threading.Tasks;
using Windows.System;
...

async Task<string> LaunchAppForResults()
{
    var testAppUri = new Uri("test-app2app:"); // The protocol handled by the launched app
    var options = new LauncherOptions();
    options.TargetApplicationPackageFamilyName = "67d987e1-e842-4229-9f7c-98cf13b5da45_yd7nk54bq29ra";

    var inputData = new ValueSet();
    inputData["TestData"] = "Test data";

    string theResult = "";
    LaunchUriResult result = await Windows.System.Launcher.LaunchUriForResultsAsync(testAppUri, options, inputData);
    if (result.Status == LaunchUriStatus.Success &&
        result.Result != null &&
        result.Result.ContainsKey("ReturnedData"))
    {
        ValueSet theValues = result.Result;
        theResult = theValues["ReturnedData"] as string;
    }
    return theResult;
}

В этом примере в запущенное приложение передается ValueSet, содержащий ключевой элемент TestData. Запущенное приложение создает ValueSet с ключом с именем ReturnedData, который содержит результат, возвращенный вызывающей стороне.

Прежде чем запускать вызывающее приложение, необходимо создать и развернуть приложение, которое вы запустите для получения результатов. В противном случае LaunchUriResult.Status сообщит LaunchUriStatus.AppUnavailable.

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

string familyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;

Замечания

В этом руководстве представлено введение в пример "hello world" для запуска приложения с целью достижения результатов. Важно отметить, что новый API запуска LaunchUriForResultsAsync позволяет асинхронно запускать приложение и обмениваться данными с помощью класса ValueSet. Передача данных через ValueSet ограничена 100 КБ. Если необходимо передать большие объемы данных, вы можете предоставить общий доступ к файлам с помощью класса SharedStorageAccessManager для создания маркеров файлов, которые можно передать между приложениями. Например, если у вас есть ValueSet с именем inputData, вы можете сохранить токен в файл, которым вы хотите поделиться с приложением, которое вы запускаете:

inputData["ImageFileToken"] = SharedStorageAccessManager.AddFile(myFile);

Затем передайте его в запущенное приложение через LaunchUriForResultsAsync.