Handling application updates with App Installer and MSIX in Windows 10 19H1

Published Feb 22 2019 07:47 AM 24.8K Views

A while ago we have explored a feature added in Windows 10 1803 called App Installer, which allows to create powerful deployment experiences with AppX / MSIX packages.

Thanks to App Installer, you're able to deploy a package (with its optional dependencies) on a web site or an Intranet share and let your users to download from it, instead of using the Microsoft Store or a similar infrastructure. You have also the opportunity to enable automatic updates, exactly like the Store does: every time you deploy an updated version of the package in the same location, Windows will take care of automatically updating the application.

Updates checks can be configured in two ways:

  • Every time the application starts. In this case, the update will be automatically downloaded and installed when the application is closed.
  • At a specific frequency (for example, every 6 hours). In this case, the update will be automatically downloaded and installed if the application is not running; otherwise, it will be installed as soon as the application is closed.

Everything is controlled by a XML file, with .appinstaller extension, which is deployed on the server together with the AppX / MSIX package you want to distribute.

This is an example of an App Installer file:

<?xml version="1.0" encoding="utf-8"?>
<AppInstaller Uri="https://msix-appinstaller.azurewebsites.net/MyEmployees.Package.appinstaller" Version="" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2">
  <MainBundle Name="97437f1b-36c5-47b0-9f3d-9f5aaa5c5aab" Version="" Publisher="CN=mpagani" Uri="https://msix-appinstaller.azurewebsites.net/MyEmployees.Package_1.0.0.0_Test/MyEmployees.Package_1.0.0.0_x86_x64.msixbundle" />
    <OnLaunch HoursBetweenUpdateChecks="0" />

The two relevant nodes are:

  • MainBundle, which specifies the Uri and the info about the MSIX package to deploy.
  • UpdateSettings, which configures the auto update feature. The HoursBetweenUpdateChecks attribute can be set to 0, in case you want to check for updates every time the app is launched, or to a fixed value, in case you want to enable periodic checks.

The App Installer file is simply a XML file, so it can be manually created with any text editor. However, the simplest way to generate it is through Visual Studio. When you trigger the process to create a MSIX / AppX package (right click on the UWP / Windows Application Packaging Project and choose Store -> Create App Packages), you can opt-in to enable automatic updates.



In this case Visual Studio will generate, other than the AppX / MSIX package, also the relevant App Installer file, ready to be deployed on your web server or local share. The output will include also a HTML page, which enables your users to start the installation process:




The Get the app button simply includes a link to the .appinstaller file using the appinstaller protocol, which is natively supported by Windows:



Thanks to this protocol the user won't have to download any files, but the installation experience will be automatically triggered:




In this post we're going to see 4 new App Installer features that were highly requested and that have been implemented in 1809 and the upcoming 19H1 update:

  • Automatically notify the presence of an update
  • Support critical updates
  • Support downgrades
  • Programmatically check for updates using a dedicated API

The first 3 ones can be implemented without any code change, while the 4th one is dedicated to developers. Let's start to see them in more details!


Moving to the new App Installer version

In order to leverage the new features described in this post, you will need to use the new App Installer definition. The versioning is defined through the xmlns attribute of the AppInstaller element. The current version looks like this:

<AppInstaller Uri="https://msix-appinstaller.azurewebsites.net/MyEmployees.Package.appinstaller" Version="" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2">

This is, instead, the definition of the new version:

<AppInstaller Uri="https://msix-appinstaller.azurewebsites.net/MyEmployees.Package.appinstaller" Version="" xmlns="http://schemas.microsoft.com/appx/appinstaller/2018">

As you can see, the suffix of the schema is changed from 2017/2 to 2018. The other requirement, as per the title of this post, is to use Windows 10 19H1. The next version of Windows 10 is still in development and, as such, you can get it for the moment through the Windows Insider program.


New update experience

The current implementation of automatic updates has a limitation. If you deploy an update on the server and the user opens the application, he won't know that there's a new version until he restarts it. In some cases (think, for example, to a critical business app which is always kept open and rarely restarted), it may take a while before the conditions for the update to be applied are satisfied.

Windows 10 19H1 has introduced support for an update prompt. When the user starts the app and there's a new update available, he will see a prompt with a notification. The user will have the option to apply the update immediately or to continue opening the app and apply it once it's closed.

This is the user experience:




In order to enable this behavior, it's enough to add a new attribute in the App Installer file called ShowPrompt and set it to true:

  <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="true" />


Critical updates

With the previous feature, you can show a prompt to notify the user that an update is pending. However, he's still able to open the app and postpone the update at a later time. What if the update contains a fix for a critical bug and users shouldn't be allowed to launch an outdated version of the app? Thanks to a new attribute, now you can also mark an update as critical and force the user to install it before opening the app.

This is the user experience:




As you can see from the message, the user doesn't have the option to launch the app anymore. The update will be applied anyway, regardless of his choice. The only difference is that, if he presses the Update button, the app will be started immediately after the update has been installed. If he presses Cancel, instead, the update will be applied but the app won't be launched.

In order to enable this behavior, you just have to add the UpdateBlocksActivation attribute and set it to true:

    <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="true" UpdateBlocksActivation="true" />

In order to make it working, also the ShowPrompt attribute must be set to true.


Supporting downgrades

In some scenarios, you may need to ask to your users to downgrade their application to a previous version. For example, you may have discovered a critical bug in the new version which will require some time to be fixed but, at the same time, you can't block your users for a long time. Thanks to a new App Installer feature, you can enable applications to be downgraded while, normally, you would be able to install a package only if it has a higher version number than the one already installed on the machine. However, unlike for the previous features, downgrades can't be automatically delivered, but they must be manually installed. When the downgrade feature is enabled and the user presses the Get the app button from the web page, this is the experience he will see:




The user has the ability to press the Update button, but he's warned that the current version on his machine is newer.

To enable this feature you need to add a new element to the UpdateSettings node of the App Installer file:

  <OnLaunch HoursBetweenUpdateChecks="0"/>

The element is called ForceUpdateFromAnyVersion and must be set to true if you want to enable this feature.


Check for updates within the app

In some scenarios you may want more flexibility in handling the update story. For example, you could offer an option within the app to check for updates; or you can implement, within the app, a periodic check, so that you can immediately warn the user that there's a new version available, without waiting for him to close and restart the application. Before Windows 10 1809, the Universal Windows Platform included some APIs to check the availability of updates, but they were reserved only to applications published on the Microsoft Store. Now, instead, you can check for available updates also when the application is manually distributed using an App Installer file.

If your application is built on top of the Universal Windows Platform, you're good to go. Otherwise, if it's a Win32 application, you will have to integrate the UWP ecosystem in your project. You will need to add a reference to two files:

  • Windows.md, which contains the metadata that describes all the APIs of the Universal Windows Platform.
  • System.Runtime.WindowsRuntime, which is a library that contains the infrastructure required to properly support the IAsyncOperation type, which is used by the Universal Windows Platform to handle asynchronous operation with the well known async / await pattern. Without this library your options to interact with the Universal Windows Platform would be very limited, since all the APIs which take more than 50 ms to return a result are implemented with this pattern.

Let's see the required steps for a WPF or Windows Forms application:

  1. Open your project in Visual Studio, right click on it and choose Add reference.

  2. Look for the following folder on the system: C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0. If you don't have it, you must install first the Windows 10 SDK which ships with Visual Studio. Alternatively, you can download the specific installer from the official website.

  3. Change the dropdown to filter the file types from Component files to All files. This way, the Windows.md file will become visible.


  4. Click on it and press Add.

  5. Now press again the Browse button. This time look for the following folder on the system: C:\Windows\Microsoft.NET\Framework\v4.0.30319

  6. Look for a file called System.Runtime.WindowsRuntime.dll, select it and press Ok.

  7. As last step, expand the References section of your project in Solution Explorer and look for the Windows reference.


  8. Right click on it and choose Properties .

  9. Change the value of the Copy Local property from True to False.

That's it. Now you can leverage APIs from the Universal Windows Platform in your Win32 application. The one we're looking for to check for updates is part of the Windows.ApplicationModel.Package class. Here is a sample usage:

private async Task CheckForUpdates()
    var result = await Package.Current.CheckUpdateAvailabilityAsync();
    if (result.Availability == PackageUpdateAvailability.Available)
        MessageBox.Show("There's a new update! Restart your app to install it");

As you can see, the API is pretty simple to use. You just call the CheckUpdateAvailabilityAsync(), which will return an enumerator of type PackageUpdateAvailability. The result can assume different values, based on the update status. In the sample, we just use the Available value to determine if there's indeed an update so that we can inform the user with a message. You could also check for the Required value, in case you want to apply a different logic if there's a critical update.


Wrapping up

In this short post we have seen some new features that have been added to App Installer in Windows 10 19H1, which addresses many feedbacks received from developers and IT Pros. Now, other than just enabling auto-updating, we can also notify the user that an update is pending; we can handle critical updates; we can support downgrade; we can provide a customized user experience. Thanks to these improvements, MSIX and App Installer are becoming more and more a great choice when it comes to distribute applications interanlly in your enterprise or to your customers!

Occasional Visitor

Is it possible to create different update channels (using this method)?


Hello, not automatically. You would need to publish different versions of the application with a different identity on different websites, otherwise, if you keep the same name and publisher, the apps will "overlap" each other.

If you have this requirement your best chance is to use the Microsoft Store, since it supports the flighting concept. You can define multiple "rings", each of them with a set of specific users. When you publish an update on a specific ring, only the users included in that ring will get it. All the other will continue to get the standard "stable" version from the main channel.

You can find more details here: https://docs.microsoft.com/en-us/windows/uwp/publish/package-flights 

Occasional Contributor

Thank you for the article, @Matteo Pagani. I searched far and wide for this information.



Is the app installer supported in Windows 10 IoT Core?


Good question :) I don't know the answer out of the box, let me do some digging.

Occasional Visitor
How can you have one appinstaller file being used by devices with different Windows versions.? want to have one file that Windows 10 1803, 1809 and 1903 use to update using the OnLaunch element.

Hello, if you use an .appinstaller file which contains some features which are supported only on newer versions of Windows 10, they will simply be ignored by earlier versions. For example, if you specify the ShowPrompt attribute, it won't cause any effect if the user is running Windows 10 1809. The application will continue to be silently updated. If the user is on Windows 10 1903, instead, he will see the prompt once there's an update available.

Occasional Visitor
I'm not sure about that. I tried with an .appinstaller with schema http://schemas.microsoft.com/appx/appinstaller/2017/2 that had showprompt="" is="" defined="" in="" the="" =""> App installation failed with error message: error 0xC00CE015: App manifest validation error: The app manifest must be valid as per schema: Line 12, Column 41, Reason: The attribute 'ShowPrompt' on the element '{http://schemas.microsoft.com/appx/appinstaller/2017/2}OnLaunch' is not defined in the DTD/Schema. (0xc00ce015)
Occasional Visitor
I'm not sure about that. I tried with an .appinstaller with schema http://schemas.microsoft.com/appx/appinstaller/2017/2 that had ShowPrompt="true". ShowPrompt is defined in the http://schemas.microsoft.com/appx/appinstaller/2018 schema. The App Installer UI showed the following message on a Windows 10 1903 device: App installation failed with error message: error 0xC00CE015: App manifest validation error: The app manifest must be valid as per schema: Line 12, Column 41, Reason: The attribute 'ShowPrompt' on the element '{http://schemas.microsoft.com/appx/appinstaller/2017/2}OnLaunch' is not defined in the DTD/Schema. (0xc00ce015)

The right schema URL to support ShowPrompt is http://schemas.microsoft.com/appx/appinstaller/2018. Using this schema shouldn't block you to use this AppInstaller file on Windows 10 versions earlier than 1903. Did you give it a try?

Occasional Visitor
Yes, if I increase the schema I can use the .appinstaller file on 1903 and 1809, but not on 1803. I would like to not increase the schema because Windows 10 1803 devices will not be able to use the .appinstaller, which is something that I absolutely need (not all devices that run our app are on the latest Windows version). If there was a way to have schemas not depend on Windows version, many problems would disappear. Let's say if I add ShowPrompt to an .appinstaller with 2017/2 schema, ignore it when an 1803 device uses the .appinstaller, but if a 1809 or 1903 device uses the file, consider ShowPrompt. What do you think?
Occasional Visitor

I have a very strange problem attempting to update using app installer and I have no idea where to ask about it, or to report it as a bug except maybe here.


My application installs fine.  On updating it and launching it, the update is detected fine.  On clicking the button to install the update it fails with the following lines being written to AILog.txt


ERROR: StartInstallOperation -> Install Operation Failed: 0x80070057

GetErrorMessageFromHResult -> Message: [The parameter is incorrect.]


Watching the update process in Fiddler, I can see that the appinstaller file is read in its entirety numerous times and then two overlapping range requests are issued for a very small part of the msix package.  


I cannot understand what "parameter" can be incorrect since the application installs fine and the msix can be updated directly from powershell.


Rather I wonder if it is this strange range request processing that is buggy and the failure is in fact an internal one when it calculates its next wacky range.


Is there anything I can do to troubleshoot this further?


Hello Glen,

would you have the chance to share the MSIX package and the AppInstaller file? I will be happy to help troubleshooting this and reach the PG for investigations.

If yes, just send me a mail at name.surname@microsoft.com with all the details.

Occasional Contributor

How to initiate an update in an application and track its progress? Application is deployed on a web site, not the app store. I've tried StoreContext, context.GetAppAndOptionalStorePackageUpdatesAsync() and it throws an error: "The operation attempted to access data outside the valid range (0x8000000B) Exception Type: Exception Exception BaseType: Object Exception Module: System.Private.CoreLib.dll (System.Private.CoreLib.dll)" so, I presume that is not the way when the app is not on the app store. What is the correct way, if one exists?


It just came to me that I could run a URI to a .appinstaller when an update is available. ;)


Hello, take a look at the last paragraph of the blog post: you need to use the following API




if you're using sideloading with App Installer. The StoreContext API works only if the application is published on the Microsoft Store. This API is documented here: https://docs.microsoft.com/en-us/uwp/api/windows.applicationmodel.package.checkupdateavailabilityasy...



Occasional Visitor

Just checked on Windows 10 IOT January Refresh (1809) and neither the initial MSIX install nor auto-updates appear to be working. It asks what app to open the .appinstaller file with.


I guess that Windows 10 IOT misses the AppInstaller component. It can be downloaded from the Microsoft Store: https://www.microsoft.com/en-us/p/app-installer/9nblggh4nns1 

Occasional Visitor

Is there an offline installer for that app? The install button on the web version of the Windows Store does nothing on this particular Windows IOT installation, and there's no Windows Store app installed either.


Yes, you can get it from the Store for Business: https://businessstore.microsoft.com/en-us/store/details/app-installer/9NBLGGH4NNS1 Here is the procedure to acquire offline apps: https://docs.microsoft.com/en-us/microsoft-store/distribute-offline-apps#download-an-offline-license... I'm not 100% sure it would work on Windows 10 IoT, but it worthies to give it a try.

Occasional Visitor

Hmm, I'll take a look at this, but unfortunately our customers do not typically have Windows Store for Business accounts setup. We've been distributing UWP apps as MSIX packages that install and auto-update over their intranet, but so far we've only managed to get this working on a regular windows 10 pro install, not the IOT version. Our only other alternative would be to wrap the app in a ClickOnce installer that just runs the Powershell install script, but it's not a great solution...


The Store for Business account isn't needed for everyone of your customers. You can just grab the offline package with your own account and then redistribute the offline package. But, again, I'm not 100% sure this would work on the IoT version. I need to check internally.

Occasional Visitor

Thanks! Just one question, Auto-updates is binary diff? Or it download entirely the new version and replace the older?


Hello @Brouilles , it makes a binary difference down to 64 KB level. Windows will download only what actually changed compared to the previous version.

Occasional Visitor

Is there an option to override the update-check and package download mechanism?

Alternatively, is it possible to manually download an update package and install it offline?


Hello @omeran80 , what do you mean by "overriding the update check"? If you have access to the source code of the application, you can also leverage the PackageManager APIs to trigger the update from the application itself. You can see an example here: MSIX-Labs/DeveloperLabs at master · microsoft/MSIX-Labs (github.com)


But yes, also manually downloading the update and install it offline is a supported scenario. As long as the package you're installing as a higher version number, you're good to go.

Occasional Visitor

Just an update from my previous post: We got confirmation that MSIX auto-updating functionality is NOT supported on Windows IoT. There was mention of an upgraded license to include it but it didn't look like the IoT version of Windows so I think they were talking about a regular desktop Windows SKU. This was definitely a major blocker for us, so we ended up needing to take the drastic step of porting the app to the web.


As a point of hopefully constructive feedback - I think the team at Microsoft that developed the ClickOnce framework understood that it was meant as a way of distributing native Windows apps (particularly enterprise apps) in a way that was close to the simplicity of distributing a web application. It may not have been very sophisticated, particularly with respect to version management, but it got the job done 90% of the time and we've relied on it for many years. It doesn't appear to me, from the architecture and behavior of the MSIX framework, that it was intended to address this important use case.


We need the following in order to consider MSIX again:

- It needs to work on every version of Windows (ClickOnce apps still work on Windows IoT! At least while Edge still supports them...)

- It needs at least the option to force the app to update before launching. This is an enterprise app.



Hello @JeroMiya, in order to have automatic updates you must have the App Installer feature included (Get App Installer - Microsoft Store). You can find it also on the Store for Business, if you're looking for a package to sideload. Just to clarify, which Windows SKU are you using? IoT Core or IoT Enterprise?


Regarding your requirements, App Installer supports forcing the app to update before launching, as detailed here: App Installer file update settings - MSIX | Microsoft Docs You need to enable both the ShowPrompt and UpdateBlocksActivation in the OnLaunch configuration. When you do this, the user will see a prompt if an update is available, but the only options are to close the app and update, or to continue the update and launch the app. He won't have anymore the option to postpone the update.





Occasional Visitor

Hi @Matteo Pagani, and thanks for your reply.

My problem is not with triggering the update check, but with performing the update check itself -

My company's public site does not allow a simple URL for downloading the AppInstaller/MSIX files, and requires a slightly more complex protocol to retrieve them.

At the worst case I could perform the check/download myself and let MSIX installer to continue from there, but if I can integrate it into the standard flow, I gather that it would be much better.



Occasional Contributor



Using the MSIX latest packaging tool, I managed to convert our Win32 installer, which contains a Windows service, into an app package. We'd like to take advantage of the app installer functionality to automatically update this app package. So far, when I tried to install the app package from our Azure website, it returns 'unknown error'. So I can't debug anymore. I use a very simple app installer file.

A few months ago, I was able to handle the auto update with our Azure website on a different Win32 application containing a background process.
So, is it possible to auto update an app package which contains a Windows service using the app installer feature?




Hello @adelkeita , I don't think that the problem you're hitting is related to the package including a Windows service. I have a package published here https://msixwithservices.z6.web.core.windows.net which contains a service and it's deployed with AppInstaller and everything works fine.

I would suggest to double check that the AppInstaller configuration and, if you're using an Azure App Service, that the MIME types are properly set, as explained here: Distribute a Windows 10 app from an Azure web app - MSIX | Microsoft Docs


Keep me posted!

Occasional Contributor

Thanks Matteo for your quick response, I'll let you know when I manage to make everything works.

Occasional Contributor

Hi @Matteo Pagani,


I finally managed to install our app package containing a windows service.


Modifying the "UpdateSettings" part of the app installer file, I managed to make it work with this configuration:


     <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="false" UpdateBlocksActivation="false"/>



However I don't know why I can't use these XML attributes and elements "HoursBetweenUpdateChecks" and "ForceUpdateFromAnyVersion".


We would like to always update this app package silently without any user input.


I noticed that I'm getting error 0x80D05011, if I do this:

     <OnLaunch HoursBetweenUpdateChecks="0"/>


And I get error 0xC00CEE01:

error 0xC00CEE01: The XML in the .appinstaller file is not valid ... Reason: Unexpected end of input. (0xc00cee01)


if I do this:


     <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="false" UpdateBlocksActivation="false"/>


or this:


     <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="false" UpdateBlocksActivation="false"/>
     <AutomaticBackgroundTask />


I don't know why I can't use these "ForceUpdateFromAnyVersion" ?




Hello @adelkeita,

can you try to reboot your PC when you make these changes to the App Installer file and you get the error?

There's a known issue with caching that gives you these kind of errors when you make changes to an App Installer file after you have already leveraged it to install an application. Usually a reboot of the machine fixes the problem.


Keep me posted!

Occasional Contributor

Thank you very much @Matteo Pagani !


I've restarted my PC and now "ForceUpdateFromAnyVersion" works completely fine.


Thank you again for the support.

Occasional Contributor

Hi @Matteo Pagani 


Is it possible to customize the update prompt?

For instance, we would like to add some text and a hyperlink to let the user know about the changes in the app.




Hello @adelkeita this feature isn't supported at the moment. But it's a really good suggestion, I will open a feature request to the App Installer team.

Regular Visitor

Good afternoon,


From within the app, using the CheckForPackageAvailability API, is it possible to detect a forced downgrade? It doesn't appear that this is possible. We would like to be able to force a rollback to a previous version, should a package be found to be faulty and need to back out a version upgrade.


From the way that it looks, you actually have to run the appinstaller to detect and downgrade, but if you already have the app, it will just continue to run the later (and maybe broken) version of the app.


Is an API able to detect and schedule the downgrade automatically based on the settings in the appinstaller file? Or maybe I'm just missing something.





Hello @tjmullen2 ,

I'll ask around but, out of the box, I'm afraid that your scenario isn't supported. That API is capable only to detect forward upgrades, not downgrades.

Occasional Contributor

The code for checking updates programmatically is causing an app crash for me when installing my app on Windows 10 Enterprise LTSC build 1809. It works fine on other editions or even LTSC build 21H1.


I got it working using the `Microsoft.Windows.SDK.Contracts` NuGet package instead as described here (had to convert from package.config to PackageReference)




Sample code



var packageManager = new PackageManager();
var currentPackage = packageManager.FindPackageForUser(string.Empty, Package.Current.Id.FullName);
var result = await currentPackage.CheckUpdateAvailabilityAsync();


if (result.ExtendedError != null) {
     LogError("Update availability error", result.ExtendedError);

var hasUpdate = (result.Availability == PackageUpdateAvailability.Available);


if (hasUpdate) {

   // there is an update available






Hello @szilardd , thanks for the update.

This article was written when the Microsoft.Windows.SDK.Contracts wasn't available yet and the only way to reference Universal Windows Platform APIs from a .NET app was using the manual process described in my article.

Today, using the Microsoft.Windows.SDK.Contracts is the right way to achieve this goal if your app is based on .NET Framework or .NET Core 3.x. If you're using .NET 5 or .NET 6, instead, you can directly set the TargetFramework to a specific Windows 10 / 10 one, like net5.0-windows10.0.19041, as explained here: https://andrewleader.medium.com/new-net-5-windows-tfms-explained-55efac9405f6

Occasional Contributor

@Matteo Pagani thanks for the details.


Do you know anything about how to include the *.pdb symbol file in the MSIX package. To have line numbers included in the stack trace when an exception is logged from the application?


More details here https://gorovian.000webhostapp.com/?exam=t5/msix-deployment/msix-debugging-symbols-for-sideloaded-app/m-p...



Version history
Last update:
‎Feb 22 2019 08:14 AM
Updated by: