共用方式為


啟動應用程式以取得結果

重要的應用程式介面

瞭解如何從另一個應用程式啟動應用程式,並在兩者之間交換數據。 這稱為 啟動應用程式以取得結果。 這裡的範例示範如何使用 LaunchUriForResultsAsync 來啟動應用程式以取得結果。

Windows 10 中的新應用程式對應用程式通訊 API 可讓 Windows 應用程式 (和 Windows Web 應用程式) 啟動應用程式,並交換資料和檔案。 這可讓您從多個應用程式建置混搭解決方案。 使用這些新的 API,現在可以順暢地處理需要使用者使用多個應用程式的複雜工作。 例如,您的應用程式可以啟動社交網路應用程式來選擇聯繫人,或啟動結帳應用程式來完成付款程式。

您將用於獲取結果的應用程式稱為已啟動的應用程式。 將啟動應用程式的應用程式稱為呼叫應用程式。 在此範例中,您會同時撰寫呼叫的應用程式和已啟動的應用程式。

步驟 1:在您將用來取得結果的應用程式中註冊要處理的通訊協定

在已啟動應用程式的 Package.appxmanifest 檔案中,將通訊協定延伸模組新增至 <Application> 區段。 這裡的範例使用名為test-app2app的虛構通訊協定

通訊協定延伸模組中的 ReturnResults 屬性接受下列其中一個值:

在此協議擴展範例中,App 只能為了取得結果而啟動。 這可簡化 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.xaml.cs 中定義的 App 類別內加以建立。

在可讓您在社交網絡中挑選朋友的應用程式中,此功能可能是您開啟人員選擇頁面的地方。 在下一個範例中,當應用程式為獲取結果而啟動時,會顯示名為 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一律,因此剛才顯示的程式碼可以直接 args 轉換成 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 方法,以在應用程式啟動時顯示結果。 如果這個方法還不存在,請在 <pagename>.xaml.cs 中定義的頁面類別內建立它。 請確定下列使用 語句的 被包含在檔案的頂端:

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

OnNavigatedTo 方法中的 NavigationEventArgs 物件包含從呼叫端應用程式傳遞的數據。 數據可能不超過 100 KB,並儲存在 ValueSet 物件中。

在此範例程式代碼中,啟動的應用程式預期從呼叫端應用程式傳送的數據會位於名為 TestData索引鍵底下的 ValueSet,因為這是範例呼叫應用程式的編碼方式。

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

在此範例中,會傳遞包含 TestData 索引鍵 ValueSet。 啟動的應用程式會使用 名為 ReturnedData 的索引鍵,建立 ValueSet,其中包含傳回給呼叫端的結果。

您必須先建置並部署將用於取得結果的應用程式,然後才能執行您的呼叫應用程式。 否則,LaunchUriResult.Status 會報告 LaunchUriStatus.AppUnavailable

當您設定 TargetApplicationPackageFamilyName時,您將需要啟動應用程式的系列家族名稱。 取得家族名稱的其中一個方法是從啟動的應用程式內進行下列調用:

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

備註

本操作指南中的範例提供了一個「Hello World」的簡介,介紹如何啟動應用程式以取得結果。 要注意的重點是,新的 LaunchUriForResultsAsync API 可讓您異步啟動應用程式,並透過 ValueSet 類別進行通訊。 使用 ValueSet 傳遞的資料 有 100KB 的限制。 如果您需要傳遞較大的數據量,您可以使用 SharedStorageAccessManager 類別來共用檔案,以建立可在應用程式之間傳遞的檔案令牌。 例如,假設 ValueSet 名為 inputData,您可以將令牌儲存至您想要與啟動的應用程式共用的檔案:

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

然後,透過 LaunchUriForResultsAsync傳遞至啟動的應用程式。