Recently as a part of the debugging process, I had to dig into how Windows Universal Apps are deployed so I could ensure that all the assets in my project were being deployed correctly. I thought that it would be easy to find documentation on the process, but it wasn’t. The process inside of Visual Studio is relatively opaque, and the documentation for the package itself leaves much to be desired.
Packages and Bundles
The first step before talking through how Visual Studio manages packages and bundles is to quickly explain the difference. Packages contain a single compilation of your application. It is targeted for a specific type of processor and processing word width (32-bit or 64-bit). Each package has everything that is needed to install that version of the package to the machine.
A bundle is a collection of packages for multiple processor and word widths. Each of the individual compilations and the required files are contained in individual package files. So, a bundle is a collection of packages – literally. When you unpack a bundle, you get a set of packages.
Visual Studio Package
Visual Studio uses a Package.appxmanifest file in your project to generate the package and settings. Double-clicking on the file reveals a designer:
The interface has a series of tabs that allow you to specify the various settings in the package, including the various icons that you need for the package. However, there are numerous settings available in the XML – like what platforms your solution targets – which can only be found by editing the XML directly. For that, you’ll need to right-click the Package.appxmanifest file, select Open With… and then select one of the XML formats. The file will look something like:
Here, you’ll notice that my solution targets two devices through the dependencies tag that isn’t available in the user interface itself. However, there is a missing element that I expected: an element that allows me to specify additional files to include in the package. Though Visual Studio will include items flagged with properties of content (like the icons) and compiler output, there’s no option to include additional files directly. That’s problematic, since I want to include C++ DLL files. With no way to directly include them in the manifest, and no way to include them as references (because they’re not MSIL/.NET DLLs), I’m stuck statically binding them or manually building the package later.
Debugging and Deployment
Deploying your Windows Universal Platform package is as easy as pressing F5, thereby telling Visual Studio to run the package. However, this process doesn’t use the typical packaging process to deploy the solution. (They’re using Loose File Registration.) In fact, if you try to install a packaged version of the application before uninstalling the Visual Studio installed version, you’ll receive a warning:
The solution is to remove the version of the application that Visual Studio deployed and then deploy the package from the .AppXBundle file. Visual Studio can create the .AppXBundles for you. This is done by right-clicking the project, selecting Store, and finally Create App Package.
The wizard starts by asking the type of package you want to create:
Until you’re ready to get the app certified to go in the store, you’ll want to create a package for sideloading. That is, you want to manually deploy the package to the machines that you want it on without going through the store. When you press the Next button, you’ll see the detail settings for the package:
In this dialog, in addition to setting the output location and version, you select which compilations will be included in the bundle. Once you press Create and wait for the builds to complete, you’ll get a dialog that offers the location for the package and a gentle nudge to try to certify your application for the app store:
With the appxbundle in hand, you can directly extract the files, or you can install the package and review the files in the installed directory.
Extracting the Package
Included with Visual Studio (via the Windows SDK) is the MakeAppX.EXE utility, which can be used to create an application package and an application bundle. It can also be used to expand application bundles and packages so you can see what files are inside. This, then, can show you what Visual Studio put into your bundle. Even if you only select a single processor type and word width, Visual Studio will create an application bundle (.AppXBundle).
Both Packages and Bundles are ZIP based files so you can rename them to .ZIP and use your favorite tool to extract them if you’d prefer to do that rather than using MakeAppX.EXE to unbundle your files.
To extract the bundle, start a Developer Command Prompt for VS 2017 (or whatever version of Visual Studio you’re running), run the MakeAppX.EXE with unbundle, then /v (for verbose) /p bundlename.appxbundle /d C:\TargetDirectory, where bundlename.appxbundle is the name of the application bundle that Visual Studio created for you, and C:\TargetDirectory is the directory where you want the files extracted to.
MakeAppX.EXE unbundle /v /p BundleName.appxbundle /d C:\TargetDirectory
Once you review the directory and figure out the name of the package, you can run MakeAppX.exe again with unpack /v /p packagename.appx /d C:\TargetDirectoryPackage. Obviously packagename.appx is the name of the package, and C:\TargetDirectoryPackage is where you want the directory where the package is to be extracted to.
MakeAppX.EXE unpack /v /p PackageName.appx /d C:\TargetDirectoryPackage
Now you can review exactly which files are being deployed on the device.
Working from the Installation Directory
This approach is fine for applications you’ve created or those for which you have an .appxbundle or .appx file. But what if you want to look at what another application installed – and where? For that, you’ll need to look at the installation directory on your computer. This time, you’ll need an administrative command prompt. This can be done by right-clicking on the command prompt and selecting Run as Administrator…
The directory that the applications are installed in is C:\Program Files\WindowsApps. This folder is hidden – and it’s not one that users have direct access to. We’re going to have to first take ownership of the folder then change the permissions. The first command is the TAKEOWN.EXE command. For this, we’re going to run:
TakeOwn.EXE /F “C:\Program Files\WindowsApps”
This will set the owner of the directory to the current logged in user. The next thing we need to do is to give ourselves permissions to the folder. That’s done with the ICACLS command.
ICACLS “C:\Program Files\WindowsApps” /grant myusername:(F)
In the above line, change myusername with your username. (If you don’t know your username, type whoami and press Enter.)
Once you’ve done this, you can close the command prompt. If you don’t have hidden files visible in File Explorer, you’ll need to go to File Explorer Options (which you can get to by starting to type the name in the Start menu). When the dialog appears, select the View tab, then select the radio button to Show hidden files, folders, and drives before clicking the OK button.
Now you can open the file explorer and navigate to C:\Program Files\WindowsApps. You’ll see a listing of the packages installed on your computer. Navigating into each folder shows you what files were installed with the package:
It’s easy enough to see what is making your application package – if you know where to look.