Integrating desktop code into UWP apps with an AppService

UWP apps are great, with a clean install experience and buttery smooth touch. But what if you want to call desktop DLLs or break out of the sandbox and call desktop APIs?

You may have heard of Brokered Components that used COM wrappers to call into Win32 code, but these were quite messy to deploy, and required a certain amount of COM/C++ knowledge which if you are old enough to remember, you have probably forgotten the details. Also, because this technology required external components, registry settings and unsigned code, you couldn't use this method in apps submitted to the Store.

With Windows 10 Anniversary Update (14393, RS1, 1607) there's a new feature, the FullTrustProcessLauncher. You've probably heard of AppServices where an app can expose functionality to other apps, but did you know you can have a Win32 (eg WPF) child process and communicate with it over an AppService and bundle it as part of your AppX so it cleanly installs with your app. So imagine you have a desktop project implementing your Win32 logic and a UWP project targetting 14393 or better. You can just create a subfolder (say "Win32App") in the UWP project, and create links to your Win32App EXE and any dependant DLLs and set the build action to "copy to output". This will bundle your Win32App into your AppX and deploy it to a subdirectory called "Win32App". (Note it has to be a subfolder, it doesn't seem to work if you put the EXE in the root folder). Then your UWP can expose an AppService that the Win32App can connect to and communicate with your UWP.

Then some stuff in your manifest:

Some more namespaces:

<Package xmlns="https://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="https://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="https://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="https://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:desktop="https://schemas.microsoft.com/appx/manifest/desktop/windows10" IgnorableNamespaces="uap mp rescap desktop">

...

<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable=" Win32App\Win32App.exe" />
</Extensions>

...

<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>

Then your code calls

await Windows.ApplicationModel.FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();

which starts your Win32 process. The Win32 process then connects to your AppService and you can communicate with it:

ValueSet valueSet = new ValueSet();
valueSet.Add("stuff", "args");

if (App.Connection != null)
{
AppServiceResponse response = await App.Connection.SendMessageAsync(valueSet);
if (response?.Message != null)
...

All the communication is built into the platform! Super slick. You need to get a full trust waiver to submit apps using this technology to the Store, not sure how easy that is, but the cool thing is because your Win32App is part of your AppX, it gets signed as part of the Store process so your app even works on Windows 10S! Note the FullTrustProcessLauncher is in the desktop extension SDK. Also note that your Win32App has identity so it can call Modern APIs such as accessing the UWP's temp storage. Use the following to add Modern references to your Win32App  https://blogs.msdn.microsoft.com/lucian/2015/10/23/how-to-call-uwp-apis-from-a-desktop-vbc-app (NuGet UWPDesktop)

Also when submitting your app to the Store, if you use the standard .appxupload file you get an error. The workaround is to drill into your package folder and zip the appxbundle and the appxsym into a zip file and call it .appxupload and then upload that. Seems to get around it.

Anyway, this article was just to get you familiar with the process, there's a couple more details and bits of code you need so head right over to the SDK sample and give it a shot.

https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/AppServiceBridgeSample

Enjoy!

Paul Tallett, App Dev Architect, UX Global Practice, Microsoft, November 2017

Disclaimer: The information on this site is provided AS IS with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.