Package a .NET desktop application using the Desktop Bridge and Visual Studio Preview
09/04/2017: post updated to include a reference to desktop applications developed with C++, since CPP projects are supported as well by the Desktop Bridge Packaging Project.
In one of the previous posts I’ve written on this blog we’ve seen how, thanks to a combination of a JavaScript project for the Universal Windows Platform and a special Visual Studio extension called Desktop Bridge Debugging Project, it is possible to create a packaged version of a .NET desktop application in an easier way. Thanks to this approach, you are able to edit some parts of the manifest in a visual way; generate the app packages for sideloading or Store distribution using the same Visual Studio wizard used for regular UWP applications; debug the packaged version of your application.
However, the experience wasn’t 100% optimal: since the JavaScript project of the Universal Windows Platform wasn’t born for this specific scenario, but it was used as a workaround to avoid the compilation of the packaged application, there was still some manual work to do. However, I have a great news for you: the packaging experience is about to become a lot better and you can try it starting from today! Visual Studio 2017 Update 4, in fact, will include a new project called Desktop Bridge Packaging Project, which will make the overall experience of packaging a .NET desktop application using Visual Studio a whole lot easier. You can start playing with this new project today, since last week Microsoft has released the first preview of the Update 4 through the separate Visual Studio Preview channel, which is a different edition of Visual Studio that can be installed side-by-side with the regular one and that contains all the features that are still in beta. When they will be finalized, they will be moved from the preview to the stable channel.
Let’s see how to use the Desktop Bridge Packaging Project and how it can make our life much easier.
Installing Visual Studio Preview and packaging a .NET application
The first step is to install Visual Studio 2017 Preview, which you can get from https://www.visualstudio.com/vs/preview/. Make sure to install, as minimum requirement for the purpose of this post:
- The tools for developing Universal Windows Platform apps.
- The tools for developing desktop application based on the .NET Framework (like Windows Forms or WPF) or C++.
Now let’s start by opening your .NET desktop application with Visual Studio 2017 Preview. For the purpose of this post, I’m going to reuse a simple Windows Forms application that I wrote a while ago as a sample for the Convert phase of the Desktop Bridge journey, which you can find on GitHub at https://github.com/qmatteoq/DesktopBridge/tree/master/3.%20Convert/Convert However, the new Desktop Bridge Packaging Project will work with any Windows Forms, WPF project or C++ project. Just remember that, in case you’re using one of the first two technologies, the minimum version of the .NET Framework supported by the Desktop Bridge is 4.0, even if it’s highly recommended to target at least .NET 4.6.1.
The application is very simple. The UI includes two buttons, which both create a text file on the desktop: the only difference is that the first one includes a sample text, the second one saves instead a serialized version of an entity that represents a person by using the popular JSON.NET library. The goal of this second sample was to show how to handle, in a packaged version of a desktop application, a dependency from a 3rd party library. Both operations create the file directly on the desktop of the user, which is a task that a Universal Windows Platform app would need to perform in a different way (for example, by using the FileSavePicker API to ask to the user where he wants to save the file).
Now let’s right click on the Visual Studio solution and choose Add –> New project. In the Universal Windows Platform section, you will find a new template called Desktop Bridge Packaging Project:
Give to the project a meaningful name (I like to use the naming convention <name of the original desktop project>.Package) and press OK. The first thing you will be asked is which version of the Universal Windows Platform SDK you want to target. This choice doesn’t really have a real impact, since we’re talking about a packaged version of a desktop application and not a full Universal Windows Platform app. However, make sure to choose, as Minimum version, at least the 14393 SDK (Anniversary Update), since it’s the first edition of Windows that added support to the Desktop Bridge. If you target a prior version as minimum, you’ll get an error during the first compilation.
This how your solution will look like:
As you can see, the Convert.Package project looks like a Universal Windows Platform one. It has an Assets folder, where the various images for icons and tiles are stored; it has a Package.appxmanifest, which is the manifest file of the application; it has a temporary certificate, which is used to sign the package for testing purposes. However, instead of having a References section with the list of all the libraries used by the application, it has a new section called Applications. Its purpose is exactly to specify which applications should be included in the app package. Right click on it, choose Add reference and you will see a list automatically filtered to display only the other projects that are part of the solution which are full applications and not just libraries. In my case, for example, I’m able to see only the Windows Forms app called Convert, I can’t add a reference to a generic library:
Click on it and you will find the Convert application listed under Applications, like if it’s a normal reference. Now there’s another step to take which is required because, as we have seen in another post on this blog, an app package can contain multiple executables, which can be launched between each other. This is a very important scenario to keep in mind, especially when it comes to Windows 10 S compatibility: a Desktop Bridge app running on Windows 10 S, in fact, can launch another process using the Process.Start() method of the .NET Framework only if it’s part of the same app package. If it’s an external process, you will get an exception and the operation will fail. However, despite an app package can contain multiple executables, it can have only one entry point, which is the process that is launched when the user clicks on the tile or on the icon in the Start menu. As such, by using the Applications section of the Desktop Bridge Packaging Project, we can add a reference to multiple applications, in case our Visual Studio solution contains multiple .NET desktop projects. However, only one of them can be the starting point, which is the one that, if you remember when we had to manually edit the manifest file, was set using the <Application> tag like in the following example:
<Application Id="Convert" Executable="win32\Convert.exe" EntryPoint="Windows.FullTrustApplication">
Thanks to the new Packaging project, we don’t have anymore to manually set the entry point, but it’s enough to right click on the application we want in the Applications section (in my sample, the Convert one) and choose Set as entry point.
That’s all regarding the basic configuration. Now you can just set the Convert.Package as startup project, choose a specific CPU architecture (x86 or x64) and press the Start debugging button. The packaged version of your desktop application will be deployed and the debugger automatically attached, giving you in just one step both the advantages of the previous approach based on JavaScript and Desktop Bridge Debugging Project: automatic generation and deployment of the AppX file and a real-time debugging experience of the converted version. The debugging experience is very helpful especially if, in combination with the context identification library available on NuGet, you are planning to detect if your application is running as a classic desktop one or packaged through the Desktop Bridge and, only in the second case, take advantage of some APIs of the Universal Windows Platform (for example, to display a toast notification, update a live tile or integrate voice commands with Cortana).
As you can notice, compared to the previous approach based on the JavaScript project, there are multiple advantages:
There is no need anymore to manually setup a post build process that takes care of copying the output of the build of the Win32 project inside a folder of the JavaScript project.
No more manual editing of the manifest file. Out of the box, the included manifest is already tailored for a Desktop Bridge application. You just need to set which is the entry point but, as you have seen, the operation is done with a simple right click.
The manifest of a Desktop Bridge is fully supported by the Visual Studio editor. If you remember what happened when you opened the Package.appxmanifest file of a JavaScript project used in a Desktop Bridge scenario, there was a persistent error in the Application tab of the editor, since the entry point of the manifest wasn’t recognized as valid: it was expecting the path and name of the HTML page used as entry point of the UWP application. Now, instead, it’s set to the special value Windows.FullTrustApplication and correctly recognized.
If you remember the blog post about setting up the JavaScript project, there was some extra work to do in case your desktop application at some point started to have a dependency from a new library. By default, in fact, thanks to the post-build task, all the DLLs that were part of the library were copied inside the JavaScript project, but they weren’t included in the app package, triggering an error at runtime related to one or more missing DLLs if you forgot to include them in the build output. Now, instead, everything is handled automatically by the Desktop Bridge Packaging Project. As you may have noticed, the application used in this sample has a dependency from the library Newtonsoft.Json.dll (JSON.NET, used for the serialization of JSON data), but everything is completely transparent: the packaged version of our desktop application is deployed and launched by Visual Studio without having to perform any extra step.
Additionally, compared to the Desktop App Converter and the manual approach to create a package, you keep getting the same advantages that were offered also by the JavaScript project and Visual Studio 2017:
- Automatic generation of all required assets starting from a single image, thanks to the new tool added in Visual Studio 2017 in the Assets section of the manifest visual editor.
- Generation of the packages (both for the Store and for sideloading) using the Visual Studio wizard (available when you right click on the Desktop Bridge Packaging Project and you choose Store –> Create App Packages), instead of having to deal with command line tools like makeappx or signtool.
- Editing of the information stored in the manifest (like application’s name, capabilities, extensions, etc.) in a visual way, instead of having to manually edit the XML file.
- In case of Store publishing (which, remember, requires first to nominate your application, since your account requires a special capability), you can easily assign an identity to the application from one of the names you have reserved on the Dev Center thanks to the Visual Studio wizard Store –> Associate App with the Store. Previously, you needed to manually copy the required information (like publisher or identity name) from the Dev Center website and paste them inside the XML of the manifest file.
Wrapping up
As you have seen, using the Desktop Bridge to package a desktop application based on the .NET Framework is easier than ever. This way, you can take advantage of all the benefits of the Desktop Bridge technology: you can distribute it using the Store or the Store for Business (other than the traditional distribution channels); you can improve the deployment experience; you can start leveraging the benefits of the Universal Windows Platform and plan a migration path without having to immediately rewrite from scratch your existing desktop application. You can download the sample project used in this post from https://github.com/qmatteoq/DesktopBridge/tree/master/Extras/PackagingProject Just remember that, to open it, you need to install Visual Studio 2017 Preview first from https://www.visualstudio.com/vs/preview/. If you’ll try to open it with the regular Visual Studio 2017 version, you will get an error, since the Desktop Bridge Packaging Project won’t be recognized.
And if you’re a Windows developer, don’t miss also another important feature coming with Visual Studio 2017 Update 4: support to .NET Standard Libraries 2.0 in UWP apps built with the upcoming Fall Creators Update SDK. Thanks to this new feature, you’ll be able to leverage lot of highly requested APIs from the .NET Framework also in a UWP application, like DataSet or SqlClient to perform queries directly on a database. You can learn more in the following blog post: https://blogs.msdn.microsoft.com/dotnet/2017/08/25/uwp-net-standard-2-0-preview/https://blogs.msdn.microsoft.com/dotnet/2017/08/25/uwp-net-standard-2-0-preview/
Happy packaging!
Comments
- Anonymous
August 28, 2017
Thanks for the details! Few questions:1. would make much more sense to have a tab in Manifest Editor where we could select projects with desktop apps to include in UWP. That would make experience way better.2. is there a possibility for desktop app (non UWP, non App Container) to launch Win32 desktop bridged app within container? Think of 3rd party that I can't control that needs to launch my console app. Quite frequent scenario.- Anonymous
August 29, 2017
Hello Sergey,thanks for your feedback! Here are my answers:1) You're more than free to leave your feedback on the official UserVoice website for the Desktop Bridge https://wpdev.uservoice.com/forums/110705-universal-windows-platform/category/161895-desktop-bridge-centennial However, if I can share my opinion, I think that the current approach is the best one. The reason is that the Manifest Editor is a tool that translates in a visual way what's stored in the XML file. The information about the applications included in the app package isn't stored in the manifest (except for the entry point), so I think it would be misleading to add a new section in the Manifest editor which isn't translated into something that gets stored in the actual XML file.2) You can use the alias extension to achieve this goal: https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-extensions#aliasBest
- Anonymous
- Anonymous
October 16, 2017
Is it possible to use DualAPIPartition classes in a packaged Desktop app? I thought it was supposed to be since such an app now has a "strong app identity," but CameraCaptureUI.CaptureFileAsync() still throws InvalidOperationException when I call it from a packaged app. - Anonymous
November 07, 2017
Thanks for the detailed article. But I have some questions.Background story:I have developed a WPF based desktop application and recently I was tasked to explore the possibilities to include MyScript (https://www.myscript.com/) into the app. However, I found that MyScript is only supported on UWP based on what I've read from the documentations as well as the answer to this question in the forum (https://developer-support.myscript.com/support/discussions/topics/16000009183).So here's my questions:1. If I package my WPF desktop application into UWP app, will I be able to include MyScript into the generated UWP app?2. I have no experience in developing UWP app but as far as I can guess, I can only include MyScript into the WPF app BEFORE packaging it into a UWP app because I cannot further modify the code AFTER the packaging is done. Am I correct?- Anonymous
November 07, 2017
Hello Gilford, if the MyScript library targets only UWP I'm afraid there's no way to include it as a reference in the WPF app, since these two technologies rely on two different frameworks. What you can do, eventually, is creating a UWP application which references and uses the MyScript SDK and, by leveraging the Desktop Bridge, it invokes one or more traditional Win32 processes. The misunderstanding here I think is that the Desktop Bridge is a technology to run existing desktop applications in the UWP context, but it doesn't turn your application into a UWP one. A Desktop Bridge app will continue to run like a regular Win32 one, with the addition of some benefits regarding deployment and identity. I hope it helps!
- Anonymous
- Anonymous
December 18, 2017
Hi, matteoI want to use Windows Application Packaging Project to debug EXE inside a pure UWP app, does Windows Application Packaging Project support this? If it does, how to do it?thanks - Anonymous
December 18, 2017
another question: how to package pdb file of my Win32 EXE into UWP, so that Windows Store can use it, I can see more crash information from Store.