Desktop Bridge - Converting an installer with Desktop App Converter

Hopefully, thanks to the previous post, you have now a better picture of the scenario where the Desktop Bridge fits: it helps Win32 developers to start moving their first steps in the UWP world and getting benefits of some of his advantages, without having to rewrite the app from scratch. In this article we’ll start to have some fun and to be more technical: we’re going to take an existing installer (a MSI file) and we’re going to convert it into an AppX package using the Desktop App Converter, which is one of the available tools that are part of the Desktop Bridge.

Installing the Desktop App Converter

The first step is to make sure your computer is up-to-date with the latest Windows 10 version: Desktop App Converter, in fact, requires the Anniversary Update, which was released on 2nd August. To make sure you’re on the right version, just right click on the Start button and choose Command Prompt: at the top, you’ll see the Windows 10 build number, which should be 10.0.14393. clip_image001

If you haven’t received yet the Anniversary Update and you have a Windows Home or Pro edition, there’s an easy way to get it: got to the website https://www.microsoft.com/software-download/windows10, click Upgrade now and launch that tool that you will be prompted to download. It will take care of “forcing” the installation of the Anniversary Update if your PC is still on the November version.

Now you need to get two files:

  1. The Desktop App Converter tool itself, which can be downloaded directly from the Store at the URL https://www.microsoft.com/store/apps/9nblggh4skzw
  2. The base Windows image, which is used as container to generate the AppX package (BaseImage-14393.wim). Be aware that this file is quite big (approximately 3.3 GB). It can be downloaded from the following link: https://aka.ms/converterimages.

Important! Each Windows build needs to have a matching base image for the Desktop App Converter. As such, if you want to do some serious work with the Desktop Bridge, I strongly suggest you to keep a PC or a Virtual Machine with the Anniversary Update dedicated just to this task. The reason is that, if you’re interested in testing the new Windows 10 previews that are being released through the Insider program, the Desktop Bridge team doesn’t release a base image for each new build that gets released, especially if you’re subscribed to the Fast Ring.

Once you have downloaded the base image and installed the application from the Store, you need to launch it with administrative rights (so right click on the Desktop App Converter icon and choose Run as administrator). Under the hood, you will notice that it’s simply a Powershell command prompt, since it’s the technology that empowers the Desktop App Converter.

clip_image003

The first step is to bypass the standard Windows execution policies, otherwise you won’t be able to move on with the installation, by executing the following command:

 PS C:\> Set-ExecutionPolicy bypass

The next step is to install the base image, by executing the following command in the folder where you have copied the file you’ve previously downloaded (or, alternatively, you can pass to the -BaseImage parameter the full path of the file).

 PS C:\> DesktopAppConverter.exe -Setup -BaseImage ".\BaseImage-14393.wim" -Verbose

The operation will take a while and, at some point, it may ask you to reboot the machine: the reason is that Desktop App Converter relies on a Windows 10 features (called Containers), which isn’t installed by default. If that’s the case, the script will take care of installing it for you and rebooting the machine to enable it. If that doesn’t happen and you get an error related to the inability of properly install the Containers support, you can manually install the feature by right clicking on the Start button, choosing Programs and features and, in the left panel, the option Turn Windows features on or off. You will find one called Containers: enable it, let the installation complete and, if asked, reboot the computer.

containers

Please note! The Containers feature is available only on Windows 10 Pro or Enterprise.

To perform the conversion process, you’ll need also the Windows 10 SDK 14393 installed on your machine: the easiest way to get it is to install Visual Studio 2015 Update 3 and to make sure to perform a custom setup, so that you get the chance to install the tools to develop Universal Windows Platform applications. If you don’t have a MSDN subscription, you can get the free Community edition from https://www.visualstudio.com/products/visual-studio-community-vs

Now you’re all set and you’re ready to convert your first application.

Starting the conversion process

Before explaining the details of the conversion process, it’s important to highlight a concept that, at a first glance, it may not be immediate to understand. The Desktop App Converter tool is required only if you need to convert an installer (like a MSI) into an AppX package. If you’re starting from a standalone executable or your goal is to convert a project for which you have the source code (like a WPF or Windows Forms solution for Visual Studio), you don’t need the Desktop App Converter or to follow the steps I’m going to describe in this article.

Typically, the approach I’m going to show in the next steps is the one you’re going to leverage when you aren’t ready to start adding new features to your app or integrating UWP APIs yet, but you just want to take your existing installer and to start getting advantage of the benefits of the AppX distribution (more secure sandbox, more streamlined installation and uninstallation process, Store distribution, etc.). In the next articles, instead, we’re going to see the other approaches to start adding UWP features or components to your own code, but they won’t require to use the Desktop App Converter, but just the standard tools provided by the Desktop Bridge.

To demo the conversion process, we could use any installer, like a .msi or a .exe setup file. It’s important, however, that the installer follows the requirements highlighted in the previous article (like that it needs to support a silent install mode, without user interaction, or that it doesn’t require to install Windows services or kernel drivers).

For this demo, we’re going to use a very simple Windows Forms application I’ve created called Hello Centennial, which does a very a simple operation that a standard UWP app can’t perform: creating a text file on the user’s desktop without asking for his explicit permission. If you want to take a look at the source code, the project available on GitHub, as every other sample related to this series of articles: https://github.com/qmatteoq/DesktopBridge/tree/master/1.%20Desktop%20App%20Converter/HelloCentennial

The code is quite straightforward: the main form contains a button that, when it’s clicked, creates a file on the user’s desktop with a message.

 private void OnCreateFile(object sender, EventArgs e)
{
    string userPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
    string fileName = $"{userPath}\\centennial.txt";
    File.WriteAllText(fileName, "This file has been created by a Centennial app");
}

By using a third party application I’ve converted the .exe produced by Visual Studio into an .msi installer, which respects the Desktop App Converter requirements: it doesn’t try to install services or drivers, it’s a MSI (so it has built-in support for silent installation), etc.

You can download the .msi from GitHub: https://github.com/qmatteoq/DesktopBridge/blob/master/1.%20Desktop%20App%20Converter/HelloCentennial.msi

Now that we have a MSI to play with, we can start the conversion process using the Desktop App Converter tool. We’ll need, again, to open the tool with administrative privileges.

This is the command we’re going to execute:

 C:\>.\DesktopAppConverter.exe -Installer "C:\Installer\HelloCentennial.msi" -Destination "C:\Output\HelloCentennial" -PackageName "HelloCentennial" -Publisher "CN=<publisher_name>" -Version "1.0.0.0" -MakeAppx -Verbose -Sign

Here is the explanation of the different parameters required by the script:

  • -Installer is the path to the setup file we need to convert. In this case, it’s the HelloCentennial.msi file we’ve previously downloaded from GitHub.
  • -Destination is the folder where we want to store the output files created by the conversion process.
  • -PackageName is the name we want to give to the package.
  • -Publisher is the publisher’s name of the application. If you have some previous experience with UWP development, you’ll recall seeing this information in the manifest file of a UWP app. It’s univocally assigned by the Dev Center when you open a developer account. For the moment, for test purposes, you can just use the name you want, it’s just important that it starts with CN= and that it doesn’t contain spaces.
  • -Version is the version number of the app.
  • -MakeAppx means that, other than generating the folder which will contain all the files that needs to be packaged (like assets, the manifest, etc.), you want also to immediately generate the AppX package.
  • -Verbose is an optional parameter, which is useful because it will show you all the details of what’s going on during the conversion process.
  • -Sign is a parameter that allows to automatically generate the needed certificates to properly sign the AppX package. Without this digital signature, the package can’t be installed on a machine which doesn’t trust the generated certificate.

As already mentioned, I’ve created an installer using the MSI format, meaning that it automatically supports a silent installation process. The Desktop App Converter is able to automatically understand it and apply the required parameters to perform the installation in the proper way. However, many installers don’t work this way: they, at least, ask to the user to press a couple of Next buttons to move on with the process, to choose the folder where to install the app, sometimes to accept a license agreement, etc. In these cases, it’s likely that they still offer a silent installation mode, but they require to be launched with a special parameter (like Setup.exe /s). If that’s your case, you can specify this information with an additional parameter provided by the Desktop App Converter called -InstallerArguments. In this case, for example, the previous command would look like this:

 C:\>.\DesktopAppConverter.exe -Installer "C:\Installer\Setup.exe" -Destination "C:\Output\HelloCentennial" -PackageName "HelloCentennial" -Publisher "CN=<publisher_name>" -Version "1.0.0.0" -MakeAppx -Verbose -Sign -InstallerArguments "/s"

What happens during the conversion process? The tool will capture all the changes made by the setup during the installation (file copied, registry keys created, etc.) and will store them, so that they can be replicated in the sandbox when the app is executed into the container. This is the reason why apps distributed using AppX are more secure: all the reading operations will be performed against the real registry, but all the writing ones will be performed against a virtualized version. The isolated container will take care of merging the real registry with the virtualizing one, allowing your app to always work with a consistent and up-to-date version of the registry.

The consequence is that, when your app will be uninstalled, it will be like uninstalling a UWP app: there won’t be any leftover, neither in the file system or in the registry, which has always been one of the biggest causes of the Windows degrading performance issue over time.

At the end of the process, you will get a folder structure like the following one:

folders2

The real work done by the tool can be found inside the PackageFiles folder:

folder

As you can see, this folder looks a bit like the one that Visual Studio creates when you start a new UWP project. You have an Assets folder, which contains the default images to be used for the tile, the Store or the icon in the Start menu. You have also a manifest file, the one called AppxManifest.xml: if you open it with a text editor, you will notice that it’s similar to the manifest file of a UWP app. However, compared to a native UWP app, you’ll find a couple of differences:

  • You’ll find the following capability, which allows the application to run in full trust. This option is available only for converted apps, a native UWP apps can’t have this kind of access.

     <Capabilities>
        <rescap:Capability Name="runFullTrust" />
    </Capabilities>
    
  • You’ll find an Application entry with all the info about the Win32 process that the UWP container will launch:

     <Application Id="HelloCentennial" Executable="HelloCentennial.exe" EntryPoint="Windows.FullTrustApplication">
    

Additionally, you’ll find other files and folders that captured the MSI setup process. For example, the Registry.dat file contains all the changes applied to the registry. Or, if you explore the VFS folder, you will find all the dependencies that are copied during the installation process (like the entry in the Start Menu).

Since, in the Desktop App Converter command, we’ve added the -MakeAppx parameter, the tool has already generated for us an AppX package starting from the PackageFiles folder, which we can deploy and share with other users or, eventually, publish on the Store when we’ll be granted access.

You can immediately see one of the new features of the Anniversary Update we’ve talked about in the previous post: in the past, to manually install an AppX package without using the Store, you needed to run a Powershell script. Now, instead, you have a simple visual installer: just double click on the file HelloCentennial.appx and you’ll be prompted with the following dialog:

clip_image010

However, if you press the Install button out of the box, you’ll stumble upon the following error:

clip_image011

The reason is that, by default, a UWP package needs to be signed with a valid certificate to be installed and this certificate needs to be trusted by the computer. When we publish a UWP app on the Store, this process is completely transparent: it’s the Store that takes care of signing the AppX package with a valid certificate during the submission process. In this case, instead, we’re trying to sideload a package without using the Store, so we need to take care of signing it.

If you remember, when we used the Desktop App Converter tool, we passed a parameter called -Sign, which already did the hard work for us. The package is already signed: the problem is that the certificate used for signing it, at the moment, isn’t trusted by our computer, which leads to an installation failure.

To solve this problem, you’ll need to add the certificate in the Trusted Root Certification Authority of the computer. You’ll find it in the folder generated by the tool (the one with the AppX package and the PackageFiles folder) and it’s called auto-generated.cer: simply double click on it, choose Install certificate and, when you’re prompted where to install it, choose Local machine and then the option Place all certificates in the following store. By pressing the Browse button, make sure to choose Trusted Root Certification Authorities and complete the process.

clip_image012

After you’ve completed this operation, you can now try again to install the AppX file. This time, after pressing the Install button, you will see a progress bar showing the installation status and, at the end, the window will become like the following one:

clip_image014

Now you have a Win32 app that has been embedded into a UWP app! If you look for it in the Start menu, you will see it like any other native UWP app: it will have a tile (even if a standard one generated by the tool), you’ll be able to pin it to the Start menu and, if you want to uninstall it, just right click on it and choose Uninstall.

clip_image016

However, if you’ll launch it, you will notice that it’s still a Win32 app and it will be able to create a text file on the user’s desktop just fine, without requiring any extra dialog or permission.

The installation process

The installation of a converted app is exactly the same of a native UWP application. The content of an AppX package is uncompressed into the folder C:\Program Files\WindowsApps which, by default, is hidden and it’s not accessible by any user (even an administrator one, since the owner of the folder is a system user). This is a read-only folder and it’s the consequence of one of the requirements that a converted app has to deal with: the application can only read data from this folder, but it can’t write any file. Data can be written only in the AppData folder, which is different for each user and it’s stored in the same folder where native UWP application handle the local storage. This is an example of the path a local folder for a converted app: C:\Users\<username>\AppData\Local\Packages\D5BA6BCD.OpenLiveWriter_7g8mfyn71hpbp

<username> is the name of your Windows user, while the name of the folder (in this sample, D5BA6BCD.OpenLiveWriter_7g8mfyn71hpbp) corresponds to the Package Family Name of the application (in this case, I’ve taken as example is the converted version of Open Live Writer, the popular blogging tool which has been used to write this post).

The reason of this requirement is very simple: the AppData folder is stored inside the Windows space assigned to the user, so the app doesn’t require any administrative privilege to read and write files into this folder. The same scenario usually doesn’t apply, instead, to the folder where the app is installed. For example, one of the most popular locations where apps are installed, the C:\Program Files\ folder, is outside the user’s space, so it requires admin privileges to write to it. This is why you often get a UAC prompt during the setup process of a standard desktop app.

If you already have some previous experience with UWP development, this isn’t something new: they’re the same exact folders where a native UWP app stores the content of the AppX file (which usually matches with the content of the Visual Studio project) and its local data.

Inside this folder you will find a subfolder called AppData, which is where the local app data folder of your application will be mapped to. This means that, every time you use the following C# code to get access to the local app data folder:

 System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

your application will get a reference to this folder.

A native Win32 application, instead, creates his own AppData folder in the path C:\Users\<username>\AppData\Local

However, for the application the AppData path will be completely transparent: no matter if it’s running as native or as converted, it will automatically access to the correct location.

Updating the converted app

If you have some previous UWP development experience, you probably already hinted that you have the opportunity to enhance your application without writing a single line of code: since now you have a manifest file, you can edit it with Visual Studio or a text editor and start adding features and capabilities like protocol support, file association, background tasks declaration, etc. You can also define new assets and replace the existing ones with real images, to give to your application a better look and feel, exactly like you would do with a regular UWP app.

Additionally, converted applications have access to a set of capabilities that aren’t normally available to a UWP app, like the ability to add context menu entries in File Explorer. You can find the list of all these capabilities on MSDN: https://msdn.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-extensions

A real world example of this scenario when you use the Desktop App Converter is related to assets: by default, the tool generates a set of sample icons (a square with an X in the middle) that, of course, will need to be replaced with the real ones from your application before sharing the app or publishing it to the Store. To achieve this goal, it’s enough to change the content of the Assets folder and replacing the existing images with the real ones. Additionally, if you want, you can also tailor your converted application to better support devices with high DPIs and high resolutions, by creating multiple version of the same image at different resolutions. Thanks to a simple naming convention, Windows will automatically pick the proper version based on the scale factor assigned to the device.

By default, you need to provide at least the image in three different resolutions:

  • 44x44
  • 50x50
  • 150x150

The easiest way to provide more versions of the assets is to leverage a Visual Studio extension called UWP Tile Generator (https://marketplace.visualstudio.com/items?itemName=shenchauhan.UWPTileGenerator). After you have installed it, simply create a new Universal Windows Platform app in Visual Studio (an empty project will be fine) and add, in the Assets folder, the icon of your application at the highest possible resolution. Then, right click on it and choose the option Generate UWP tiles. clip_image018

Automatically, the extension will create, in the Assets folder of the empty UWP project, all the different versions of the image in all the supported resolutions and scaling factors. You will notice, in fact, that all the images will have the same base name (like Square44x44Logo.png) but with a prefix before the file extension, that specifies the scale factors which the image refers to (like Square44x44Logo.scale-200.png). This way, Windows 10 will automatically pick the proper version of the image, based on the resolution, DPI and viewing distance of the device where the app is running.

Now you can simply copy all the images contained in the Assets folder of the empty UWP project into the Assets folder of the converted app, replacing eventually the existing ones.

Repackaging the app

There’s an important caveat to remember: every time we change something in the PackageFiles folder created by the Desktop App Converter tool (like we just did, by replacing the assets), the AppX file that the tool has generated doesn’t automatically update itself, so we need to generate a new AppX package starting from the updated folder.

In fact, if we would try to uninstall and reinstall again the HelloCentennial.appx package after our changes, we’ll notice that the assets will continue to be the old ones.

Since, in this case, we didn’t change the actual code of the Win32 app, but we just changed the package content (the assets folder, in this case), we don’t have to go through the whole procedure of converting the MSI into an AppX using the Desktop App Converter tool, but we can just use a command line tool provided by the Windows 10 SDK, called makeappx.exe. Do you remember that, when we used the tool, we added a parameter called -MakeAppx? Under the hood, the Desktop App Converter used this tool to create the package for us.

Using this tool is quite easy: first you have to open a Visual Studio Command Prompt (you can find it in the Start menu), which has already set all the proper paths to give you access to the tool no matter which folder you are. However, in case you want to use a standard command prompt, you’ll be able to locate the makeappx.exe file in the following folder: C:\Program Files (x86)\Windows Kits\10\bin\x64\

To recreate the AppX it’s enough to execute the following command:

 makeappx pack -d "C:\Output\HelloCentennial\PackageFiles" -p "C:\Output\HelloCentennial\HelloCentennial.appx" 

The required parameters are:

  • pack, which specifies that we want to create a package.
  • -d is the path of the PackageFiles folder that was previously created by the Desktop App Converter which contains our manifest, assets and all the packaged files.
  • -p is the path and name of the AppX file we want to create.

After executing this command, you’ll find an updated AppX file, that you can install to deploy the new version with protocol support on your computer. However, if you’ll try to launch it you’ll find another surprise:

clip_image020

If you remember what I’ve explained earlier in the article, every UWP package needs to be signed (unless you’re going to publish it on the Store): however, when we used the Desktop App Converter for the first time, we didn’t need to take care of this operation, since we used the -Sign parameter which did all the hard work for us.

Now, instead, since we have manually created the package, we need to sign it by ourselves, using another tool provided by the Windows 10 SDK, called signtool.exe. However, we can reuse the certificates that were automatically generated by the Desktop App Converter (do you remember the files called auto-generated.cer and auto-generated.pfx that have been placed in the output directory)?

As such, we can just use the following command in the same Visual Studio command prompt we’ve previously used:

 signtool.exe sign /a /v /fd SHA256 /f "C:\Output\HelloCentennial\auto-generated.pfx" /p "123456" "C:\Output\HelloCentennial\HelloCentennial.appx" 

The important parameters here are:

  • -f, which is the path of the .pfx file that is needed to sign the package.
  • -p, which is the password of the .pfx file. When you automatically create the certificate using the -Sign option of the Desktop App Converter, the generated .pfx file will have 123456 as default password. This parameter is optional: if you decide to create your own certificate, in fact, you can also decide to generate it without any password protection.
  • The last parameter is the path of the AppX package to sign (the one we’ve previously generated with the makeappx.exe tool).

That’s all! Now you should be able to properly install the updated package with the correct assets.

If you don’t want to rely on the certificates automatically generated by the tool, you can also create your own and use them to sign the package: the procedure is quite simple and it’s described in this article https://msdn.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-signing. This is the best approach to use when you want to distribute the application, for example, in an enterprise environment and you want to create a certificate that will be shared among all the computers of the company.

Wrapping up

In this article we’ve seen how, starting from a MSI installer, we’ve been able to create an AppX package, keeping the best of both worlds: the flexibility of a Win32 app and the better security and distribution model of an AppX package. In the end, we’ve seen how, since what we get is simply a UWP package, we can start tweaking the app without writing actual code, by editing the manifest file or changing the default assets.

What if you have changed something not just in the package definition, but also in the Win32 application (like a new feature or a new piece of code)? In this case, you would have needed to go again through the whole conversion process:

  1. Generating a MSI installer starting from the Windows Forms executable
  2. Running the Desktop App Converter tool
  3. Tweak again the manifest file or the assets

However, this is a different scenario than the one we have previously started with: we aren’t talking anymore about an installer, but about an executable or an app for which we own the source code and that we want to update it and turn into an AppX.

In this scenario, Desktop App Converter isn’t our friend, but we need to use a different approach, which we’re going to see in the next article.

Remember that you can find all the samples described in this article and in the next ones in the following GitHub repository: https://github.com/qmatteoq/DesktopBridge

Happy coding!