UWP with Desktop Extension – Part 3

desktop_yellow

If you haven’t read part 1 or part 2 of this series yet, please start there first. I have covered the “Hello World” version of a UWP with Desktop extension and explained how to launch different process types and pass in arguments. Now the next set of questions I want to answer in this post are:

  • How to establish a communication channel between the components?
  • How to send requests and receive responses from either side?
  • How to handle process exit scenarios?

TL; DR;

Short answers: An AppServiceConnection can be used to connect between the components and to allow bi-directional communication via ValueSets. Typically you want to host the AppService in-proc with your UWP app in this type of scenario.

Just show me the code on github …
https://github.com/StefanWickDev/UWP-FullTrust/tree/master/UWP_FullTrust_3

Let me run your sample from the Microsoft Store …
https://www.microsoft.com/store/apps/9NR0G35Q2F65

Declaring the AppService

The first step is to declare the AppService extension in our manifest, which is what will provide us with a two-way communication pipe between our components:

<Extensions>
 <uap:Extension Category="windows.appService">
  <uap:AppService Name="SampleInteropService" />
 </uap:Extension>
 <desktop:Extension Category="windows.fullTrustProcess" Executable="FullTrust\FullTrust.exe" />
</Extensions>

For full details on AppServices in the Universal Windows Platform our developer documentation has this good read: https://docs.microsoft.com/en-us/windows/uwp/launch-resume/how-to-create-and-consume-an-app-service

Establishing the Connection

Now in order to establish the connection, let’s take a look at our WPF app. One of the first things it does during launch is to establish the connection to the AppService, and then retain the instance of the AppServiceConnection for the lifetime of the connection. We are also hooking up the event handlers here to receive requests and to get notified when the connection gets closed:

// MainWindow.xaml.cs in WPF project
private async void InitializeAppServiceConnection()
{
 connection = new AppServiceConnection();
 connection.AppServiceName = "SampleInteropService";
 connection.PackageFamilyName = Package.Current.Id.FamilyName;
 connection.RequestReceived += Connection_RequestReceived;
 connection.ServiceClosed += Connection_ServiceClosed;

 AppServiceConnectionStatus status = await connection.OpenAsync();
 if (status != AppServiceConnectionStatus.Success)
 {
  // something went wrong ...
  MessageBox.Show(status.ToString());
  this.IsEnabled = false;
 } 
}

On the other side in the UWP, this will now trigger the OnBackgroundActivated event, and we’ll grab a reference to the AppServiceConnection instance there as well and hold on to it.

In our case the UWP is already running in the foreground, but note that it doesn’t have to: Client processes can also connect to the AppService if the foreground app is not running. It would activate the UWP in the background and establish the AppServiceConnection. The UWP process would then continue running in the background for as long as the connection is active.

// App.xaml.cs in UWP project
protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
 base.OnBackgroundActivated(args);

 if (args.TaskInstance.TriggerDetails is AppServiceTriggerDetails details)
 {
  // only accept connections from callers in the same package
  if (details.CallerPackageFamilyName == Package.Current.Id.FamilyName)
  {
   // connection established from the fulltrust process
   AppServiceDeferral = args.TaskInstance.GetDeferral();
   args.TaskInstance.Canceled += OnTaskCanceled;

   Connection = details.AppServiceConnection;
   AppServiceConnected?.Invoke(this, args.TaskInstance.TriggerDetails as AppServiceTriggerDetails);
  }
 }
}

Sending Requests and Responses

Now that the connection has been established and either side keeps a reference to the AppServiceConnection instances, we can send requests from either side, and respond to them accordingly.

Scenario 1 – UWP sends request to desktop extension

UWP apps don’t have access to the registry. Let’s assume for an LOB enterprise scenario I need to read a certain reg key. The UWP can use a desktop extension to get the job done, by sending an AppServiceRequest that contains the requested key. The desktop extension can then query the registry and send the name/value pairs back to the UWP as an AppServiceResponse.

screenshot8

// MainPage.Xaml.cs in UWP project
private async void btnClick_ReadKey(object sender, RoutedEventArgs e)
{
 ValueSet request = new ValueSet();
 request.Add("KEY", tbKey.Text);
 AppServiceResponse response = await App.Connection.SendMessageAsync(request);

// display the response key/value pairs
 tbResult.Text = "";
 foreach (string key in response.Message.Keys)
 {
 tbResult.Text += key + " = " + response.Message[key] + "\r\n";
 }
}

This triggers the registry reading code in the WPF app. The implementation can be found here on github in the ‘Connection_RequestReceived’ event handler. In a real production scenario you wouldn’t implement this extension as a windowed WPF app of course, but instead use a headless background process. But since we need UI for scenario #2, I went with WPF …

Scenario 2 – Desktop extension sends request to UWP

To show the reverse communication flow I am just picking a dummy scenario: I will send two double values from WPF to UWP and let the UWP app respond with the sum of both:

screenshot9

// MainWindow.xaml.cs in WPF project
private async void Button_Click(object sender, RoutedEventArgs e)
{
 // ask the UWP to calculate d1 + d2
 ValueSet request = new ValueSet();
 request.Add("D1", d1);
 request.Add("D2", d2);
 AppServiceResponse response = await connection.SendMessageAsync(request);
 double result = (double)response.Message["RESULT"];
 tbResult.Text = result.ToString();
}
// in MainPage.Xaml.cs in UWP project
private async void AppServiceConnection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
 double d1 = (double)args.Request.Message["D1"];
 double d2 = (double)args.Request.Message["D2"];
 double result = d1 + d2;
 
 ValueSet response = new ValueSet();
 response.Add("RESULT", result);
 await args.Request.SendResponseAsync(response);

// log the request in the UI for demo purposes
 await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
 {
 tbRequests.Text += string.Format("Request: {0} + {1} --> Response = {2}\r\n", d1, d2, result);
 });
}

 

Handling Process Exit Scenarios

Now what happens if one side of the communication pipeline goes away, for whatever reason? It’s up to the app to handle this and decide what should happen. Generally speaking there are three options: try to relaunch the companion component, or keep going without the companion (if it’s non-essential), or failfast to terminate yourself. For our demo I will implement two scenarios:

Scenario 1 – UWP will relaunch closed WPF

// MainPage.xaml.cs in UWP project
private async void MainPage_AppServiceDisconnected(object sender, EventArgs e)
{
 await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ()=>
 {
  // disable UI to access the connection
  btnRegKey.IsEnabled = false;

  // ask user if they want to reconnect
  Reconnect();
 }); 
}

private async void Reconnect()
{
 if (App.IsForeground)
 {
  MessageDialog dlg = new MessageDialog("Connection to desktop process lost. Reconnect?");
  UICommand yesCommand = new UICommand("Yes", async (r) =>
  {
   await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
  });
  dlg.Commands.Add(yesCommand);
  UICommand noCommand = new UICommand("No", (r) => { });
  dlg.Commands.Add(noCommand);
  await dlg.ShowAsync();
 }
}

Scenario 2 – WPF will terminate itself when UWP closes

// MainWindow.xaml.cs in WPF project
private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
{
 // connection to the UWP lost, so we shut down the desktop process
 Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
 {
  Application.Current.Shutdown();
 })); 
}

This is it for part 3 of this series. Hopefully I answered most of the question around communication between the app and its extension in this sample. If not, please leave comments here, hit me up on Twitter or post your questions on Stackoverflow. If they are tagged with ‘UWP’ they will show on my radar.

Next up: Part 4 – Submitting to the Microsoft Store

92 thoughts on “UWP with Desktop Extension – Part 3

  1. Hello Stefan,

    Thank you for this lesson.

    At this moment I develop an extension for Microsoft Edge based on native messaging. Could you please consider this official example? https://github.com/MicrosoftEdge/MicrosoftEdge-Extensions-Demos/blob/master/SecureInput/NativeMessagingHostInProcess/App.xaml.cs

    So my question is how to handle multiple connections to the app correctly? In this sample there is very strange synchronization in the OnBackgroundActivated method and no such a thing in other methods…

    Well I did some experiments and it seems that OnBackgroundActivated is always executed by only one thread, but RequestReceived and ServiceClosed event handlers for different connections can be executed by several threads and the same time… Thus a correct synchronization for dictionaries is required.

    Could you please shed more light on this?

    Like

    1. Yes, that’s correct. The event handlers may fire on different threads and things will get more complicated if you have more than one client for your AppService. This would be a good thing to cover in an additional, dedicated sample.

      Like

  2. Hi Stefan,

    Great lessons for desktop extension!

    I am having UWP app written in C++, and I want to add desktop extension, again written in C++. Your example from part 2 shows it is possible to have UWP with C++. My question is, can I
    establish “channel” in between for information exchange? Concept of AppService is great, but as far as I saw, it can’t be used from pure C++. Or, there is something else you can propose?

    Regards,
    Aleksandar

    Like

      1. I am not aware of a plain C++ sample that uses an AppService, but you could use any C++ sample that uses WinRT APIs as starting point. There isn’t really anything special about using AppService APIs vs any other WinRT APIs.

        Like

      2. Hello Stefan –

        I’m sorry to bother you again, but I have one more question about AppServiceConnection.

        I have not seen where AppServiceConnection supports a sustained data flow model. By this, I mean setting up a data flow between client and server where the server is sending data through an event – as opposed to the server sending one piece of data at a time via request from client.

        It is true that the client could send repeated requests for data (a polling model), but that seems clunky and would most likely result in poor performance.

        If no such AppServiceConnection data event-driven model is supported, then it would seem that the best solution would be to have the client display such data directly (such as through its own WPF UI).

        Thanks again,
        Robert

        Like

      3. No need to do polling. The AppServiceConnection object has a RequestReceived event:
        https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.appservice.appserviceconnection.requestreceived?view=winrt-19041

        Furthermore, when sending a request, the sending process will be handle the response from the receiving process asynchronously:
        https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.appservice.appserviceconnection.sendmessageasync?view=winrt-19041

        Like

  3. Hello Stefan,

    Really great article on how to communicate between UWP and Windows Application.
    I have implemented WPF application as a service and UWP application as a client, following all above steps I’m able to read Registry, able to check the Process using “System.Diagnostics.Process” from a service.

    The only question I had in mind though, will Microsoft Store allow/accept my application when I will be submitting it to Store to verify and publish the same, as we are checking other applications registry and checking for the Process which is not allowed in UWP application.

    Thanks in advance!

    Like

  4. Hello Stefan,

    Really great article on how to communicate between UWP and Windows Application.
    I have implemented WPF application as a service and UWP application as a client, following all above steps I’m able to read Registry, able to check the Process using “System.Diagnostics.Process” from a service.

    Only question I had in mind though, will Microsoft Store allow/accept my application when I will be submitting it to Store to verify and publish the same, as we are checking other applications registry and checking for the Process which is not allowed in UWP application.

    Thanks in advance!

    Like

      1. Sorry for the late reply, I just returned from vacation.

        What you describe is allowed and can be accepted in the Windows Store, unless you do other things in the app that would violate Store policy. Hope this helps.

        Thanks,
        Stefan

        Like

  5. Hi Stefan,

    I am using visual studio 2017 with SDK 16299 installed, but when I build UWP_FullTrust_3, I am having a warning “warning MSB3245: Could not resolve this reference. Could not locate the assembly “Windows” and some errors

    error CS0234: The type or namespace name ‘ApplicationModel’ does not exist in the namespace ‘Windows’ (are you missing an assembly reference?)
    error CS0234: The type or namespace name ‘Collections’ does not exist in the namespace ‘Windows.Foundation’

    Do you know what’s wrong about it? Where can I add reference to assembly “Windows”.

    BR,
    CY

    Like

  6. Me again…
    In my Win32 Winforms app, I’m trying to open the connection using

    status = Await connection.OpenAsync()

    the error list shows
    Await requires that the type ‘IAsyncOperation(Of AppServiceConnectionStatus)’ have a suitable GetAwaiter method.

    Think that I can do what I want in a WinForms VB app but not sure 🙂

    Like

      1. Just realized it’s a NuGet package but the package wouldn’t install since it’s supposedly not compatible since the app targets .NET Framework v.4.7.2

        Like

      2. I know it’s not exactly obvious, but you can just add the reference to the DLL located in \Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll

        Like

  7. Stefan, Great Stuff!

    My question is more related to the capabilities of the AppService. We have a Windows service that we want to talk to from a UWP app. We can use any IPC mechanism as we have control over it. Our current environment is Service WPF app using WCF over a ManedPipe. Is an AppService able to use any of the current MS IPC mechanisms to communicate to a Windows Service, or is a Windows service able to create and use a connection to an AppService like you show in this article?

    Thanks for any insights you might have

    Like

  8. Sort of new question… I’ve got a UWP app that exposes an AppService & houses a BackgroundTask. The AppService is working fine and accepting messages from external apps via an AppServiceConnection. The BackgroundTask is registered and getting triggered when it should via OnBackgroundActivated. The problem I’m having is talking back to the external app from the BackgroundTask. The task code is in App.xaml.vb and the AppService is in class VB file that’s all part of the same solution. The AppServiceConnection is live in the class code but is inaccessible in the BackgroundTask. Not sure if what I’m doing is possible or makes sense

    Like

    1. Yes, definitely possible. You just need to get a hold of the AppServiceConnection so that your task can access it. If your task is implemented in App.xaml.vb it should be very easy as I assume this is also where your OnBackgroundActivated handler is. In that event handler you can get to the AppServiceConnection via the event args (it’s on a property a couple of levels deep: args->TaskInstance->Details->AppServiceConnection) and then store it in a class level variable. Take a look at this OnBackgroundActivated implementation (C#): https://github.com/Microsoft/DesktopBridgeToUWP-Samples/blob/master/Samples/UWP%20Office%20Interop/DataGrid2Excel/App.xaml.cs

      Liked by 1 person

      1. Looks good.. the trigger for my background task is a toast notification so the args I get are ToastNotificationActionTriggerDetail args but I can cast them as AppServiceTriggerDetails args also but not sure if that’s going to work

        Like

      2. What I meant was: grab the AppServiceConnection (from the AppServiceTriggerDetail) when the external app connects. Then keep that instance around in a class level variable. This way, when your toast notification comes in, you can use the connection to communicate with your external app. Does this make sense? Let me know if I misunderstood your scenario.

        Like

  9. When I declare the connection as such:
    Public NotInheritable Class Notify
    Implements IBackgroundTask

    Shared AppServiceDeferral As BackgroundTaskDeferral = Nothing
    Public Shared Connection As AppServiceConnection = Nothing

    Public Sub Run(taskInstance As IBackgroundTaskInstance) Implements IBackgroundTask.Run

    AppServiceDeferral = taskInstance.GetDeferral()
    AddHandler taskInstance.Canceled, AddressOf OnTaskCanceled
    Dim details As AppServiceTriggerDetails
    details = taskInstance.TriggerDetails
    Connection = details.AppServiceConnection
    AddHandler Connection.RequestReceived, AddressOf AppServiceConnection_RequestReceived

    End Sub

    and then reference it in my OnBackgroundActivated routine as such:

    Protected Overrides Async Sub OnBackgroundActivated(args As BackgroundActivatedEventArgs)
    MyBase.OnBackgroundActivated(args)
    Dim deferral As BackgroundTaskDeferral = args.TaskInstance.GetDeferral()
    Dim conn As AppServiceConnection = NotifyComponent.Notify.Connection

    I get this error upon compiling:
    Type ‘NotifyComponent.Notify’ contains externally visible field ‘Windows.ApplicationModel.AppService.AppServiceConnection NotifyComponent.Notify.Connection’. Fields can be exposed only by structures.

    Like

    1. I am not a VB expert, but I think you are declaring the Connection property as an instance property, so you will need the actual Instance of Notify to access it. This seems more complicated that it should be. I would just keep track of the AppServiceConnection in the App class and expose it from there (like I do in the example I pointed you to).

      Like

      1. The only problem with that is that the connection is created in the Notify class with is the entry point for the AppService and it doesn’t look like I can put the entry point for the AppService in the App class

        Like

      2. How do you currently declare the AppService in your appxmanifest? Make sure you run the AppService in-proc with the UWP app (unless you have a good reason not to do so). Then your AppService entrypoint is OnBackgroundActivated in the App class and all of this gets very easy (as described in the sample code I linked earlier).

        Like

  10. Here’s the relevant part

    If I can move the AppService into the UWP app that probably would clean stuff up. Currently the extension is in the same solution but a different project class file. I tried to quickly move the AppService into the UWP app into app.xaml.vb but the connection from the client app didn’t work at all. I changed the EntryPoint to something like App.Notify or something similar.

    Like

    1. The manifest part didn’t get through somehow. The key point is to declare it without specifying an entry point. Then the AppService will be activated in the same process as the app, via the OnBackgroundActivated event.

      Like

  11. Leaving out the Entry Point fixed just about everything. Thanks. Now the only ‘problem’ now is that when I click on a toast notification, but not the button on it, it brings up the UWP app’s splash screen and doesn’t hit the OnBackgroundActivated event even if I click on the toast from the Action Center. I’m guessing that another launch event gets hit.

    Like

    1. Looks like clicking on the body of a toast the app creates sends it through the OnActivated event while clicking on the button in the toast sends it through the OnBackground event

      Like

      1. This is unrelated to the topic of AppService and Desktop Extension. The activation type of your toast (foreground vs background) depends on what you specify in your app code for the toast. You can read up on this here:

        https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/send-local-toast#handling-activation-1
        https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-schema#toastactivationtype

        Like

  12. I got so wrapped up in the other stuff that I forgot that toast stuff has foreground & background. Now that program flow is working OK, it’s toast configuration that’s the problem… except that ToastHeader doesn’t allow for Background activation, only ToastButton, etc 🙂

    Like

    1. Yep, that’s how notifications work system-wide. And users are trained to expect that clicking on the body will open the foreground experience. They would likely think your app is broken if it wouldn’t behave the same way.

      Like

      1. Solved my ‘problem’ – set both the ToastHeader & ToastContent to use protocol activation, set the protocol to a new one and wrote a tiny handler that just opens & closes invisibly. The UWP app never appears, just the way I wanted it.

        Thanks for all the help.

        Like

  13. Hi Stefan,

    I am using visual studio 2019, but when I create my WPF project I am having an errror about using System.Windows.ApplicationModel

    error CS0234: The type or namespace name ‘ApplicationModel’ does not exist in the namespace ‘Windows’ (are you missing an assembly reference?)

    Do you know what’s wrong about it? Where can I add reference to assembly “Windows”.

    In the UWP project I haven’t the problem. There the reference is found.

    thanks
    Ema

    Like

    1. I assume you are referring to Windows.ApplicationModel (not System.Windows.ApplicationModel). For this you need to add a reference to Windows.winmd. To do so, select “Add Reference”, change the filter to “All Files (*.*)” and browse to %ProgramFiles(x86)%)\Windows Kits\10\UnionMetadata\{sdk_version}.

      Like

      1. thanks Stefan, I solved my problem, In the WPF project, I added the reference for Windows.winmd and two more. If anyone has problem with this, I write here my path for these references:
        C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.WindowsRuntime.dll

        one more questions Stefan. Now I’m able to launch the WPF application from the UWP project and, using the Appservice, I created the communication between the projects, but the WPF window is opened in a separete window. There is a way to integrate the WPFwindow in the same UWPwindow?

        thanks a lot
        Ema

        Like

  14. My application is a wpf tray application, and sometimes the application should display a full-screen interface. I want to use UWP design for controls. What should i use? XAML Island or desktop extension?
    I read your good article and I’m not sure which technology I should use. (I want to publish my app to MS Store)

    Like

    1. At the time I wrote these posts XAML islands didn’t exist yet, so it has not been included here as an option here. Also I have moved to work in Azure since 2018, so I am not an authority anymore on the latest about Windows desktop app development.

      A couple of things to consider though: XAML islands require Windows 10 version 1903 or later, so you won’t reach any customer who are running older versions of Windows 10. With a UWP desktop extension you can reach customers all the way going back to version 1607.

      Looking ahead though, using WinUI 3.0 is probably going to be the right choice for your scenario. It’s in alpha state right now, but once released it will allow you to add XAML UI to Win32/WPF apps and work on all prior versions of Windows 10.

      https://docs.microsoft.com/en-us/uwp/toolkits/winui3/
      https://github.com/microsoft/microsoft-ui-xaml/issues/717

      Like

  15. Thanks stefan, can you suggest what changes I have to make if my uwp supports multi-instance. Current method gives me compiling error.

    Like

      1. Please post full details if you want to get help. This is not enough info to diagnose the problem. Ideally post it on stackoverflow, tagged with “uwp” and “desktop-bridge”. This way you have the highest chance of getting an answer, and others will benefit from the discussion as well.

        Like

  16. I have 2 page on UWP app. 1 page is main page, second settings page.
    How can i open specific UWP page from extension?

    To open UWP app from extension i use this:

    IEnumerable appListEntries = await Package.Current.GetAppListEntriesAsync();
    await appListEntries.First().LaunchAsync();

    Like

    1. There are two ways to accomplish this:

      1) from your extension write the name of the desired page into local appsettings, and then read that value from the UWP during OnLaunched and then navigate accordingly:
      https://docs.microsoft.com/en-us/windows/uwp/get-started/settings-learning-track

      2) implement protocol activation for your UWP and then use that to launch it from the extension with the desired parameter(s):
      https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/september/modern-apps-protocol-registration-and-activation-in-uwp-apps

      The latter is a bit more involved but is also more robust and offers more flexibility, for example if you want to pass in multiple parameters in the future.

      Like

      1. Is this a warning in the debug spew, or does the app actually break? What happens when you create and install the app as an actual package (i.e. not run it from Visual Studio)?

        Like

      2. It is debug output from Visual Studio. It marked as “Program output”.
        My app works fine, this message does not crush my app. The app also works good when i create package and run without visual studio.

        Like

  17. Hi Stefan,
    My question is : Can a non-trust (means completely independent .NET application) can connect to a UWP app using APPServiceConnection.

    The .NET application is very independent application and its have no link with UWP app. Please share your thoughts

    Thank you very much

    Like

      1. Thank you for your quick reply. Will go through the sample code.
        Will share if any doubt.

        Like

  18. Hi Stefan,

    Does the .NET client needs to have Message loop ( means any UI).

    With UI .NET client it is working but without UI it is not connecting.

    Please share your comments.
    Thank you

    Like

  19. Yes it is working. I was running the client in Administrator mode that is why it was failing.

    After running both in as log in user, working fine. There is no dependency of UI thread

    Thank you very much for your input.

    Like

  20. Yes it is working. Its my mistake that client was running as Administrator ,
    After both running as log in user, It is working fine.

    Thank you for your input

    Like

  21. Hi Stefan,Thanks for great article.
    I am working on a React native windows project, which create a UWP c++ application project solution and then native modules are added which are written in c# winrt UWP library. (Reference: https://microsoft.github.io/react-native-windows/docs/getting-started)
    I would like to achieve what is mentioned in this article for C++ uwp application, but I don’t see App is derived from Application class, with which OnBackgroundActivated can be overriden.
    So, I tried out of process with IBackgroundTask (https://docs.microsoft.com/en-us/windows/uwp/launch-resume/how-to-create-and-consume-an-app-service), for which we need to specify entry point for App service in package manifest file, but the issue is that, when App service client (i.e. desktop extension) tries to connect, AppServie provider spwans a new process. Though I save the connection context, it is in new background process, hence I am unable to access connection handle in UWP application and make calls to client.
    Need your help on this.

    Like

  22. Hi Stefan,

    I’ve tried this post approach for using AppService. What I have is:

    WPF Desktop Extension.
    UWP App
    Both packaged into a Package project.

    Package.appxmanifest define the service, alias and capabilities (fullTrust, allowElevation, etc).

    Scenario 1. Elevation is not needed

    UWP calls await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(“User”);
    WPF Desktop Extension is launched, calls OpenAsyn() for starting communication to the service.
    Communication is successful and both UWP and WPF apps can send and receive messages.

    Scenario 2. Elevation is required

    UWP calls await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync(“Admin”);
    WPF Desktop Extension is launched, performs self elevation and shutdown current (not elevated) instance.
    WPF new elevated instance calls OpenAsyn() for starting communication to the service.
    OpenAsync() returns AppServiceUnavailable.

    Both scenarios are running exactly the same code, in same package, everything is the same. The only difference is in scenario 2 the WPF EXE elevates itself before calling OpenAsync().

    Am I missing anything here? I con not figure out why it works in scenario 1 but not in the scenario 2.

    Thanks in advance for any help you can provide me.
    Eduardo

    Like

      1. Hey Stefan,

        Ooohh… What a pity 😦

        AppServices seems to be a very clean and simple implementation approach for Win32 and UWP process communication. Can’t understand why the limitation.

        Anyways. It is what it is, and if that is not possible I will definitely need to find a different mechanism for cross-process communication, since my requirements need elevation in some scenarios.

        Can you suggest a better/different approach for me to follow?

        Basically this is what I need:

        _____________ __________________
        | | Some communication method | |
        | UWP App | | Elevated App |
        |___________| |_______________ |

        Based on my requirements, the elevated App could be a C# or C++ (Console or Windows).

        Thank you very much for your quick reply and help.

        Bests,
        Eduardo

        Like

      2. I am afraid there is no “one size fits all” answer I can give you here. Also I have left the Windows team 2 years ago, so I am no longer an authority for providing current Windows app platform guidance. There is a spectrum of inter-process communication options available on Windows. The right choice will likely depend on how complex/chatty your communication is. For simple things you may be able to get away with something simple that is file-based. For more complex scenarios RPC might be a good option, etc.

        Like

  23. Hi,

    I need to display the upload and download speed value in UWP application (Windows 10 Anniversary edition (10.0;build 14393) )as a Message Box.
    I would like to know if there is a possibility to run an external internetspeed calculator.exe (non Visual Studio) file as a background process in UWP and display the output results as a Message Box in UWP app?

    Like

    1. Yes, it works as explained in my posts about UWP with desktop extensions. You will need to write some to communicate from your EXE to the UWP, so that the UWP can then display the dialog on behalf of the EXE.

      Like

      1. Thanks Stefan. I created a windows application to run the external .exe file. Created a new UWP package (consisting of UWP and Windows application) .

        When I debug the new package,I get the following errors:

        1) .pdb files are not getting recognized (loaded).

        2)On reaching this line
        If (ApiInformation.IsApiContractPresent(“Windows.ApplicationModel.FullTrustAppContract”, 1, 0))

        I get error as “apiiinformation.cpp” is not loaded.

        I added all the capabilities in the new Package appmanifest.

        Like

      2. Unfortunately I won’t be able to provide debug support on my blog. Please open a question on Stackoverflow and tag it with ‘desktop-bridge’ and ‘UWP’. Folks from the support team and/or members of the community will be there to help.

        Like

  24. Thanks Stefan –

    Worked like a champ! SendMessageAsync() provides the event-driven model I was looking for.

    Best regards,
    Robert

    Like

  25. Hi again. When you close UWP app, the AppService also closed. Is there are way to keep alive connection after close UWP?
    I just reconnect when connection lost, but i think it wrong solution

    Like

  26. Hi Stefan. Great series BTW. I had a question about another closing scenario. When I close my UWP I want to keep my Winforms app to be able to bring the UWP back to the foreground using a system tray action for example. When I establish a new connection the OnBackgroundActivated method is triggered on UWP but the UI is not displayed. Is there a way to bring it back to the foreground and have the UI appear?

    Like

      1. That worked but now I end up with 2 Winforms instanced because of how my form is created
        await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();

        Any idea how I can make sure that doesn’t happen?

        Like

      2. You can make your Winforms app a singleton. I don’t have the code handy here, but a quick web search for winforms singleton should give you some pointers.

        Like

      3. Thank you. What I ended up doing is getting the processes running the Winforms EXE. if there is more than one I don’t create a new form and the second instance just stops.

        Like

Leave a comment