MSIX Tutorial: A comprehensive 24-chapter guide
1. What is MSIX?
Announced in 2018, at Windows Developers Days, MSIX is a new universal package format designed for Windows 10 apps. Desktop, mobile and all other Windows 10 devices will be supported.
Microsoft presented MSIX to us as an improved version of the AppX package (initially used only for UWP apps) to better support traditional desktop applications on Windows 10, by bringing along the knowledge they have from MSI and App-V packages and the Desktop Bridge program.
An MSIX package is very similar with an AppX or App-V package, structure wise. It is basically a zip package that contains your application files and some configuration XML files. In this blog post Microsoft talks about the early beginnings of this package format, i.e., the AppX, its ancestor.
The main difference MSIX brought is its extended support for Win32 applications, i.e., the standard desktop applications that we’ve been using all these years. This will allow you to package your normal desktop application and publish it in the Microsoft Store or simply offer it for download from your website while leveraging all the new advantages from the modern Windows APIs.
Packaging a desktop application as an MSIX package comes with some limitations, imposed by Microsoft to ensure the security the new model promises us. Check the article linked above to make sure your application is suitable for migrating to MSIX.
2. MSIX Container
The MSIX container brings together the support from Desktop Bridge apps with the one UWP apps, as depicted below.
Of course, classic Win32 applications packaged as an MSIX will still run only on desktop devices, therefore, these apps do not “become“ universal simply because we are now packaging them in a new format.
All these converted apps are still x86 and x64 bit apps, thus they cannot run on tablets/phones or other devices. There is one exception, the Always-Connected-PC devices, running Windows 10 in S mode, where Win32 apps run on ARM devices with an emulation support included in the OS and specific ARM CPUs.
Just as full UWP apps, the Win32 converted apps(and packaged as MSIX) can access the UWP APIs. However, from a Win32 app, you can access only the desktop APIs, while from a full UWP app you have the possibility to access different APIs (Mobile, Xbox, HoloLens, etc...), depending on the target devices.
This means that know you can start modernize your Win32 application using the new Windows 10 APIs, even migrate the entire app to the UWP, in which case you can get all the benefits of a full UWP container.
Publishing Win32 converted apps in the Microsoft Store is possible, but only for targeting the devices mentioned above.
3. System Resources & More
The MSIX container will provide access to the new Windows 10 features, like enhanced security and access to new UWP APIs, but at the same time it will also impose some limitations.
A complete list of Microsoft’s recommendations and limitations can be found in the following article, prepare to package an app (Desktop Bridge).
Below you you can find a diagram with the supported OS resources (of a Win32 application) that an MSIX package can install. Of course, on top of this you can migrate and extend your application to use the new UWP components (app services, background task, etc...) to better integrate with the OS or other applications.
If you're looking for drivers, these are not supported in MSIX packages. Microsoft recommends that all drivers be uploaded the Microsoft Store by the hardware providers, so the OS manages their installation automatically for the end user. As MSIX is still in development, we can expect changes, but until then you can still use the hybrid-solution adopted by App-V folks, where drivers still got deployed with our old friend, the MSI package.
4. Building MSIX Packages
There are multiple tools that can help you build and maintain your MSIX packages. For a full list of tools check out the Microsoft documentation.
Of course, Advanced Installer can build MSIX packages, from scratch or by converting your old installer to a new project which you can maintain. Check out the video below to see how easy you can build MSIX and MSI package from a single project, easily serving both old Windows 7 users and the current Windows 10 ones.
Microsoft provides its own tool for converting old installers, the MSIX Packaging Tool, without generating a project. Visual Studio currently builds AppX packages, so most likely in a future update we will see support for MSIX packages too.
Manually building the package is also possible, using the command-line utility MakeAppx.exe.
5. Migrate and Extend
Converting your installer is just the first phase (if your software is still maintained/updated). Now you can start working on extending your app with the new UWP APIs and migrate it step by step
The AppConsult team from Microsoft has written some excellent tutorials that show how to leverage the new APIs and start modernizing your application.
- Invoking a Win32 process from a UWP app
- Expanding a desktop application with UWP APIs
- Adding an UWP component to a desktop application
- Identifying an application context
We all know there are still a lot of clients running on Windows 7 (even if that number is dropping each day), that is why the last tutorial linked above shows how you can detect if your application is running in the old desktop app mode or the new modern app container. This way you can still modernize your app while still supporting your Windows 7 clients.
Besides converting old EXE/MSI installers to MSIX you can also convert AppX and App-V packages to MSIX format. This can be done with Advanced Installer or with the MSIX Packaging Tool. The conversion of such packages can be automatized, because unlike the MSI/EXE installers these packages do not contain any custom code that can be executed during their installation/publishing (App-V deployment config are the subject of another talk), so the entire conversion process is practically split in two simples steps:
- Extract App-V or AppX package contents
- Package the new MSIX, using the extracted (and “translated”) contents from the original package
The translation phase is the part where the new package manifest is generated/translated from the old manifests found in App-V and AppX packages.
6. Install Location
All MSIX packages are installed/extracted by the OS in the following folder:
This is a system location, inaccessible, by default, from Windows Explorer. There are methods to make it visible, but that is not the subject of this article.
Inside that folder, you will find subfolders for each app installed on the machine, including the OS built-in apps. All folders have their name following this pattern:
Here’s an example of a folder name:
Inside the folder lies the extracted MSIX package, just as you see it if you would extract it with 7-Zip or other similar tools.
Only the OS can write in this location when installing your app. If your app is writing log files or other data inside the installation folder it will crash.
You need to either update your code to write to %AppData% or, if you don’t have access to the code, use the Package Support Framework to fix it.
7. Uninstall Cleanup
Most of the times, when you uninstall an MSI package the application files from AppData and the registry entries, the app has created during its lifetime are left on the machine, polluting the system with “garbage.”
MSIX packages, on the other hand, simplify the install and uninstall process by reducing machine clutter.
Due to its containerized model, uninstalling an MSIX package will also remove from the system any files the app has created while running (under its AppData folder), including the all the app files installed under %ProgramFiles%WindowsApps.
The same thing will happen with the registries created by the app. This helps keep a clean machine state much easier and thus avoid the all known Windows Rot (aka Registry Rot).
Keep in mind that if the app also creates files in other non-standard (not recommended) location on the machine, those files will not be deleted upon uninstall.
8. File Redirections
Apps installed through MSIX packages run in a sandbox environment (i.e. the container), meaning the OS redirects most of the files and registry operations.
When it comes to files access, the redirection kicks in automatically when you are trying to access files from your package’s VFS ( Virtual File System) and AppData folders.
Accessing resources from your VFS folder can cause problems for many apps, but is very easy to fix, using the reflection APIs, as in the linked example.
The same article also explains how to access the app’s AppData folder. Windows automatically remaps the know path C:\Users\<username>\AppData\Roaming\ to a path looking like this:
Handling your AppData from the old code will work by default (including on Windows 7), the folder remapping is transparent, as long as you are using the recommend Windows APIs to retrieve the AppData folder path. (hardcoded paths are bad and will crash your app).
The above folder, where the OS redirects your app is good to know about mainly for debugging purposes.
Recommended API calls for retrieving your AppData folder paths:
//local app data string localPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); //roaming app data string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
9. Registry Redirections
All registry operations are redirected into special per-app registry hives. Your package can contain the following hives, visible in separate files if you extract its contents:
All the HKLM entries will go under Registry.dat file, while the per-user registry entries will go to the corresponding hives.
All these hives are virtually merged at run-time with the registry found on the OS, to allow the app to “see” the entire registry as a singular unit.
The HKLM registry is most of the time read-only, while write operations to the user hives are redirected to a per-app location, just as it happens with AppData files.
This allows the system to easily delete all the registry used/created by the app during its lifetime, upon uninstall, and avoid the all-known registry rot that is slowing down Windows machines for decades.
10. Digital Signing
All MSIX packages must be digitally signed, no exception. Security breaches are taking down entire companies and Microsoft decided to help tackle these attacks by enforcing digital signing for all MSIX packages, no matter if the packages install from the Microsoft Store or are sideloaded internally inside your company.
There are two ways to sign a package:
- If you, as a software vendor, publish the package in the Microsoft Store, you don’t need to sign it. Microsoft will sign the package, once they approve your app.
- If you publish the MSIX package for direct download on your website or simply plan to redistribute it internally in your company you need to sign it with a valid code signing certificate bought from a certified vendor.
For internal company apps you can even use a self-generated certificate, but make sure that certificate is also installed on the machines where you plan to deploy your MSIX, otherwise those machines will not recognize the certificate. The certificate must be found under “Local Machine -> Trusted Root Certification Authorities” certificates store.
To sign a package you need the Windows SDK. Inside the SDK you can find SignTool.exe, the command-line utility that Microsoft recommends for digitally signing.
Most packaging tools integrate SignTool automatically, so enabling digital signing is only a simple setting in their GUI.
Important: SHA256 hash algorithm is mandatory for digitally signing MSIX packages, SHA1 is not considered as valid by the OS.
11. Package Content Layout
Contents of an extracted MSIX package
The above image lays out the most common, and minimal, MSIX package layout. You can see these resources if extract the package using makeappx.exe or tools like 7-zip.
Assets - As the name implies, this is where all the app’s graphics assets should be found.
VFS - This folder normally contains the app’s binaries, DLLs, EXEs, config files and so one. Read this article for more details. The VFS and Assets folder are also known as the app payload.
Resources.pri - This file contains app resources, like localized strings and paths for additional resource files. Packages contain one file per language. Read more.
AppxManifest.xml - This XML file is the main resource from the package, as detailed in the following chapter below. It contains all the info required by the system to identify, install and run the application.
AppxBlockMap.xml - This is a file generated automatically that contains a list of all the app’s binaries and their hashes. It is used by the system for integrity checks and when performing differential updates (lowering bandwidth usage by downloading only the changes files).
AppxSignature.p7x - This file stores the digital signature information for the package contents.
[Content_Types].xml - Contains information about the types of content in an MSIX package, used by the system at install time.
This XML file is the package manifest, that must be present in any package. It contains the information defining the application and its features. All this information is used by the system to install/uninstall, update and control the app’s behavior during its lifetime.
This file is usually generated automatically by the tool building the MSIX package, be it Visual Studio, Advanced Installer or other tools. You can also create it manually, but it is not recommended. This file ends up in the installation folder of your app and it is read-only
The contents of the file must follow the schemas imposed by the OS, as documented in the link above. The schemas may differ between different major Windows 10 updates, therefore it is very important to know what OS versions you’re targeting with your app, otherwise, you might end up with using features that are not available for all your users.
13. Package Support Framework (aka PSF)
The Package Support Framework (PSF) is Microsoft’s solution for enterprise customers that need to solve compatibility problems for old desktop applications and don’t have access to the source code.
The PSF brings support for API redirection and hooking. Thus, you can fix an app that failed to write a file in the installation folder (this is no longer allowed) and redirects it to a recommended location, or maybe simply update the app’s working directory.
The way it works is pretty simple. Microsoft provides an app launcher, a runtime manager DLL, some runtime fixes and a config.json file. You can also build your own fixes following their documentation.
Their launcher (executable) will become the main app in your package, loading the runtime manager DLL and the fixes. Upon launch, this executable will automatically launch your app, but it will also load the runtime DLL and the fixes into your app, as specified the config.json file
This way, when the app is trying to access a resource that is no longer available, for example write in its installation folder, the runtime fixes will kick in and redirect the call, in this example to a new location under AppData.
How PSF works
14. Modification Packages
Practically, this package type is the equivalent of MST files (MSI transforms) from old days. However, a modification package is not directly tied to a certain version of your main app, this means you can update the main app and still use the old modification package.
It will allow IT folks from enterprises to customize and prepare for mass deployment the MSIX packages they receive from ISVs or that they generate from older installers. All this by using tools like Advanced Installer or MSIX Packaging Tool.
A modification package has the same file extension as an MSIX package, but with slightly different contents, with the major differences being found in the AppXManifest.xml file. Also, it must have the same signature (CN) as the target package, otherwise it will fail to install.
A modification package cannot define app entries inside its manifest, it can only add new binaries to the main/target package, as well as new registry entries.
Modification packages are not directly listed in “Apps and Features”, but you can find them if you access the link “Advanced options” for the target app.
15. Store Publishing
To publish an app in the Microsoft Store you need to register for a developer account with Microsoft, as an individual or a company account.
The next step is to reserve your app name. At this time Microsoft will check if the name you require is available, if not you will be prompted to specify another one.
Once your app is ready, you can submit it to the store. Before submitting it we recommend you use the Windows App Compatibility Kit (WACK) to validate your app meets Microsoft’s requirements. If your app passes all the checks it’s ready for the store.
If you’re using Advanced Installer, this validation is one-click away, just go to File -> Settings -> Package Validation” and enable WACK validations.
MSIX packages can be installed from the Microsoft Store or by launching the package directly (sideloading, i.e. manual or scripted installation) on the machine.
There are 2 major conditions that need to be met for a package to be successfully sideloaded:
- Sideloading must be enabled on the machine, using an enterprise policy or through the Settings app.
- The MSIX package must be digitally signed with a certificate recognized by the machine. As mentioned in the Digital Signatures section, the code-signing certificate can be self-generated or purchased from an authorized issuer.
Once these conditions are met, you can install the MSIX package. You can do that by either double-clicking the MSIX file or by using the PowerShell cmdlet Add-AppxPackage.
This feature means software vendors are not forced/locked to distribute their apps through the Microsoft Store. If they wish, they can publish the MSIX package directly for download on their website and the users can download and install it manually, as explained above.
The auto-updates support from the system for modern apps will still work even for sideloaded apps if the software vendors publish an update package on their servers. Read the Auto-updates section for more details.
Updates deployment is a daunting and time-consuming task, not loved by most developers, but necessary.
With MSIX packages this task is drastically simplified. If you choose to publish your app in the store you can simply stop worrying about applications updates, as the OS will take care of it for you.
For sideloaded apps, you can publish the updated package on your website along with an AppInstaller file. (below you can find the contents of a sample appinstaller file).
<?xml version="1.0" encoding="utf-8"?> <AppInstaller Uri="https://uwpupdate.azurewebsites.net/DesktopBridge.Package.appinstaller" Version="18.104.22.168" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"> <MainBundle Name="c6c08364-cbe5-4267-ae81-ce9be33ff652" Version="22.214.171.124" Publisher="CN=mpagani" Uri="https://uwpupdate.azurewebsites.net/DesktopBridge.Package_126.96.36.199_Test/DesktopBridge.Package_188.8.131.52_x86_x64.appxbundle" /> <UpdateSettings> <OnLaunch HoursBetweenUpdateChecks="0" /> </UpdateSettings> </AppInstaller>
In your main application, all you need to do is to specify the URL or the UNC path of the file share where you are going to deploy your .appinstaller file and your package. This usually can be specified in the GUI of the application you’re using to build the MSIX package. This is how you can do it with Advanced Installer and Visual Studio.
If you have even more complex scenarios for checking and downloading application updates than you might need to include an auto-updater tool next to your app.
18. App Installer (GUI)
The AppX package, the predecessor of MSIX, could not always install the package with a simple double-click. The only way to manually install/sideload an app on the machine was with the help of the PowerShell cmdlet Add-AppXPackage.
As you can see in the following Microsoft article a simple GUI was introduced to simplify the installation of MSIX packages.
Unlike the old MSI packages, this GUI is not customizable from inside the package, this means you cannot display a custom installation dialog to your customers or request for user input during the installation. Microsoft recommends for the app configuration to take place when the users first launch it, as detailed in our next chapter, First Launch Configurations.
19. First Launch Configurations
With the introduction of AppX packages, back in Windows 8, Microsoft released new guidelines for application configuration.
For all apps installed through an AppX/MSIX package, the user configurations will take place the first time the app is launched by the user. This means the installation UI can no longer be customized to gather user input and execute your own code to prepare the app before the first launch.
Microsoft recommends for all this to be done from inside your app, decoupling the install phase from the initial configuration of the app.
For enterprise deployment, were end-users usually expected their apps to be pre-configured and ready to work with, the IT departments will be able to use modification packages to include next to the app the additional configurations required (eg. a license file, etc.).
The Resource Management System is the one helping the user build the Package Resource Index ( PRI files). The PRI file is just a table of named resources and references to the resource file inside the app package and there is one PRI file per language included in each MSIX package.
Advanced Installer or Visual Studio, depending on what you’re using, will build this file automatically, based on your project configuration.
At install time, the system will automatically download only the resources it needs depending on the user’s locale and not the entire MSIX package (which also contains the resources for all the other supported languages)
For a more detailed overview of localized resources inside a package check this MSDN article.
Image source: MSDN Blogs
21. App Capabilities
With modern apps, for any OS resources (user pictures, internet connection or devices like the camera or microphone) that you’re trying to access permissions must be requested from inside the package manifest, these are your app capabilities.
Failing to declare them in your package will result in failure to load the correspondent system APIs and your app will not work as expected.
You can easily define your app’s capabilities within Advanced Installer’s GUI, by selecting them from the predefined list, or its equivalent in your Visual Studio project.
Defining application capabilities is required only for full UWP apps or UWP components from inside your app, for example a background task or an app service. Any old (Win32) code will still continue to run correctly even without the capabilities declared in the package, as it does not use any modern APIs to access those resources.
22. Debugging Inside the MSIX Container
Debugging your code inside an MSIX container is slightly different from the standard debugging in Visual Studio.
When you normally debug your desktop application in Visual Studio the app does not run inside a container, instead Visual Studio simply launches the main executable of your app as a simple file from disk, without being aware of the limitations imposed by an MSIX container or without being able to access the new modern APIs made accessible by the MSIX container.
This entire access is practically dependent on the AppXManifest.xml file and the duplication of the VFS folder. When debugging an MSIX packaged app with Visual Studio, what basically happens is that Visual Studio builds the MSIX package, either using Advanced Installer’s extension or using its built-in support, then the app is installed on the machine and package is extracted into a temporary location. Once the app is launched by the debugger, Visual Studio attaches to its process and you can proceed to debug it, just as you did in the past.
23. Per User Deployment
By default, apps deployed on the machine are registered per-user, even if they all are installed under %ProgramFiles%\WindowsApps folder, which might lead you to incorrectly think that the app is visible to all users from the machine, as it was the case for Win32 apps.
Every user will see under his account only the apps registered to his credentials, so if another user installed a new app on the machine, that app will be hidden for all other users.
If two or more users install the same app version on the machine, the application is not downloaded or installed twice. Instead, the same source is used to serve the app to both users, by registering the app with their respective accounts. This way the OS reduces disk waste and also bandwidth usage when updating the app.
Per-machine deployment can be achieved by provisioning your package before the user accounts are created, on an operating system from a local computer or on a mounted Windows image. This can be done with the Add-AppxProvisionedPackage cmdlet, for .appx and .msix packages. Read more about per-machine deployment.
24. Windows 10 S Mode
Windows 10 S mode makes the OS work exclusively with apps from the Microsoft Store.
The system shipped in S mode can be upgraded to the Professional edition, for a $49 one time fee, and thus unlocking for installing apps from all sources, including using the old installers (EXE, MSI, etc...). This is a one-way operation, going back to S mode is no longer possible after the upgrade.
Devices shipped with Windows 10 S mode seem to be Microsoft’s answer to Google’s Chromebook, which are wildly popular among educational users. Affordable machines that in the end run a fully-fledged version of Windows 10, but with some improvements (to make it run better on low specs) and the corresponding limitations those improvements bring along.
MSIX packages created with Visual Studio, the MSIX Packaging Tool or Advanced Installer can be installed on these machines without any problems, as long as you publish them in the Microsoft Store.
This is not the same thing as the Windows RT version Microsoft launched with Windows 8. Those devices were using ARM processors, thus not being able to run x86 compiled apps. Current devices shipped with Windows 10 S mode come with x86 based CPUs.
There is one exception, the new line of devices Always-Connected-PC, that will still be running on ARM. However, this new generation of ARM can emulate the x86 instructions set, so your desktop apps will still run with some limitations.