上一篇咱們討論了UWP和Desktop Extension交互中,Desktop Extension執行後當即退出的場景。下圖是提到的四種場景分類:html
本篇咱們討論第二種,Desktop Extension等待request後,根據傳參完成操做後退出的,短生命週期場景。該類型有如下特徵:git
該場景的示意圖以下:github
咱們依然以Desktop Extension啓動mspaint.exe和control.exe來舉例。和上一篇不一樣的是,此次咱們會經過UWP端發起的request來傳遞參數。安全
本篇Sample Code中的AppServiceHandler,以及App.xaml.cs中的OnBackgroundActivated方法。請參考《2020年的UWP(2)——In Process App Service》,相同部分再也不介紹。async
本篇新增的AppServiceConnectionConnectedEventArgs對象及Connected事件,是當AppServiceConnection經過OpenAsync方法成功鏈接時,傳遞當前活動的AppServiceConnection對象,以便調用SendMessageAsync等方法。this
public class AppServiceConnectionConnectedEventArgs : EventArgs { public AppServiceConnection Connection { get; } public AppServiceConnectionConnectedEventArgs(AppServiceConnection connection) { Connection = connection; } } public event EventHandler<AppServiceConnectionConnectedEventArgs> Connected;
在AppServiceHandler中的OnBackgroundActivated方法中,咱們首要作的,便是通知訂閱對象,有AppServiceConnection被成功Open了,請及時響應。spa
public void OnBackgroundActivated(AppServiceTriggerDetails details) { Connected?.Invoke(this, new AppServiceConnectionConnectedEventArgs(details.AppServiceConnection)); Connection = details.AppServiceConnection; Connection.RequestReceived += Connection_RequestReceived; }
訂閱這個Connected事件的,通常都是Desktop Extension的發起方。好比說UWP端的某個Button。code
private async void ButtonLaunchApp_Click(object sender, RoutedEventArgs e) { if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0)) { AppServiceHandler.Instance.Connected += Instance_Connected; await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(); } } private async void Instance_Connected(object sender, AppServiceConnectionConnectedEventArgs e) { AppServiceHandler.Instance.Connected -= Instance_Connected; var valueSet = new ValueSet(); valueSet.Add("FileName", ComboBoxFileName.SelectionBoxItem); var response = await e.Connection.SendMessageAsync(valueSet); }
之因此須要這個Connect事件,是由於經過SendMessageAsync傳參,須要依賴當前活動的AppServiceConnection對象。咱們正是經過Connected事件,將AppServiceConnection對象傳遞給訂閱者,使其可以訪問SendMessageAsync等方法進行數據交互。orm
在Instance_Connected方法中,在每次點擊按鈕時,均啓動一個新的Desktop Extension進程。在Desktop Extension進程中,會經過OpenAsync方法來鏈接AppServiceConnection。以後即是由OnBackgroundActivated方法觸發Connected事件,接下來就是發起request。htm
該場景中,Desktop Extension僅需維持一個較短的生命週期,在等到request後,根據傳參完成相應操做,就能夠釋放資源安全退出了。對整個APP而言,既不會長期佔用過多資源,也不會致使UWP端沒法Suspend。
下圖中的綠色葉子圖標,在Desktop Extension運行時,是不會出現的。
同時咱們要知道AppService的生命週期是不可控的,在UWP端程序最小化之後,Windows會在一段時間後中止AppService,AppServiceConnection也會被dispose。因此存儲一個AppServiceConnection長期對象,用來和永不退出的Desktop Extension通信並非個好主意。
如下是Desktop Extension端的部分代碼,爲了方便觀察應用程序的行爲,我在Sample中將Enrivonment.Exit給註釋掉了。
public async Task InitializeAsync() { Connection = new AppServiceConnection(); Connection.PackageFamilyName = Package.Current.Id.FamilyName; Connection.AppServiceName = "ParameterAppService"; AppServiceConnectionStatus status = await Connection.OpenAsync(); if (status != AppServiceConnectionStatus.Success) { Console.WriteLine(status); } else { Console.WriteLine(status); Connection.RequestReceived += Connection_RequestReceived; } } private void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var content = args.Request.Message["FileName"].ToString(); Process.Start(content); Console.WriteLine("Will exit after received."); //Environment.Exit(0); }
本篇簡單介紹了「等待request,處理完後退出」,這一UWP和Desktop Extension數據交互的場景。感謝看到這裏的同窗,單純的文字其實很難講清楚AppService的使用,還請參考Github上的實例代碼,歡迎評論及提問。