/// <summary> /// Associate the cancellation handler with the background task /// </summary> private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason, int index) { ConnectionDeferral app_dc = null; ConnectionDeferral desktop_dc = null; lock (thisLock) { if (connectionMap.ContainsKey(index)) { app_dc = connectionMap[index]; connectionMap.Remove(index); } if (desktopConnectionMap.ContainsKey(index)) { desktop_dc = desktopConnectionMap[index]; desktopConnectionMap.Remove(index); } if (taskCompletionSourceMap.ContainsKey(index)) { taskCompletionSourceMap[index].TrySetResult(false); } } if (app_dc != null) { app_dc.connection.Dispose(); app_dc.deferral.Complete(); } if (desktop_dc != null) { desktop_dc.connection.Dispose(); desktop_dc.deferral.Complete(); } }
/// <summary> /// Occurs when the other endpoint closes the connection to the app service /// </summary> private void OnConnectionClosed(AppServiceConnection sender, AppServiceClosedEventArgs args, int index) { ConnectionDeferral app_dc = null; ConnectionDeferral desktop_dc = null; lock (thisLock) { if (connectionMap.ContainsKey(index)) { app_dc = connectionMap[index]; connectionMap.Remove(index); } if (desktopConnectionMap.ContainsKey(index)) { desktop_dc = desktopConnectionMap[index]; desktopConnectionMap.Remove(index); } if (taskCompletionSourceMap.ContainsKey(index)) { taskCompletionSourceMap[index].TrySetResult(false); } } if (app_dc != null) { app_dc.connection.Dispose(); app_dc.deferral.Complete(); } if (desktop_dc != null) { desktop_dc.connection.Dispose(); desktop_dc.deferral.Complete(); } }
/// <summary> /// Receives message from Extension (via Edge) /// </summary> private async Task OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args, int index) { AppServiceDeferral messageDeferral = args.GetDeferral(); try { TaskCompletionSource <bool> tcs = null; ConnectionDeferral cd = null; lock (thisLock) { if (desktopConnectionMap.ContainsKey(index)) { cd = desktopConnectionMap[index]; } else { tcs = new TaskCompletionSource <bool>(); taskCompletionSourceMap.Add(index, tcs); } } if (tcs != null) { await tcs.Task; lock (thisLock) { if (!desktopConnectionMap.ContainsKey(index)) { return; } cd = desktopConnectionMap[index]; } } var desktopConnection = cd.connection; // Send message to the desktopBridge component and wait for response AppServiceResponse desktopResponse = await desktopConnection.SendMessageAsync(args.Request.Message); await args.Request.SendResponseAsync(desktopResponse.Message); } finally { messageDeferral.Complete(); } }
/// <summary> /// Initializes the app service on the host process /// </summary> protected async override void OnBackgroundActivated(BackgroundActivatedEventArgs args) { base.OnBackgroundActivated(args); IBackgroundTaskInstance taskInstance = args.TaskInstance; if (taskInstance.TriggerDetails is AppServiceTriggerDetails) { var appService = taskInstance.TriggerDetails as AppServiceTriggerDetails; if (appService.CallerPackageFamilyName == Windows.ApplicationModel.Package.Current.Id.FamilyName) // App service connection from desktopBridge App { var desktopBridgeDeferral = taskInstance.GetDeferral(); var desktopConnection = appService.AppServiceConnection; var connectionDeferral = new ConnectionDeferral(desktopConnection, desktopBridgeDeferral); int index; lock (thisLock) { index = desktopConnectionIndex; desktopConnectionIndex++; desktopConnectionMap.Add(index, connectionDeferral); } taskInstance.Canceled += (s, a) => { OnAppServicesCanceled(s, a, index); }; desktopConnection.RequestReceived += async(s, a) => { await OnDesktopAppServiceRequestReceived(s, a, index); }; desktopConnection.ServiceClosed += (s, a) => { OnConnectionClosed(s, a, index); }; lock (thisLock) { if (taskCompletionSourceMap.ContainsKey(index)) { taskCompletionSourceMap[index].TrySetResult(true); } } } else // App service connection from Edge browser { // Microsoft.MicrosoftEdge_8wekyb3d8bbwe var appServiceDeferral = taskInstance.GetDeferral(); var connection = appService.AppServiceConnection; var connectionDeferral = new ConnectionDeferral(connection, appServiceDeferral); int index; lock (thisLock) { index = connectionIndex; connectionIndex++; connectionMap.Add(index, connectionDeferral); } taskInstance.Canceled += (s, a) => { OnAppServicesCanceled(s, a, index); }; connection.RequestReceived += async(s, a) => { await OnAppServiceRequestReceived(s, a, index); }; connection.ServiceClosed += (s, a) => { OnConnectionClosed(s, a, index); }; try { // Make sure the tortoise_svn_opener.exe is in your AppX folder, if not rebuild the solution await Windows.ApplicationModel.FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(); } catch (Exception) { lock (thisLock) { if (connectionMap.ContainsKey(index)) { connectionMap[index].connection.Dispose(); connectionMap[index].deferral.Complete(); connectionMap.Remove(index); } if (taskCompletionSourceMap.ContainsKey(index)) { taskCompletionSourceMap[index].TrySetResult(false); } } } } } }