September 1st, 2026
0 reactions

Servicing While In Use and ERROR_PACKAGES_IN_USE

Principal Software Engineer

How does MSIX service a package while it’s in use?

Simple: It doesn’t.

A core principle of MSIX servicing is:

Do not service a package while it’s in use.

Deployment provides several ways to deal with that constraint. Options range from terminating applications to deferring servicing until the package is no longer in use.

How hard can it be?

‘Servicing a package’ means any deployment activity modifying software, including update, remove, repair and other operations.

Altering installed software can be highly disruptive if the software is in use. Executables and DLLs may be mapped into running processes. File and registry writes may be in progress. Processes may be connected through COM, named pipes, or other IPC mechanisms.

There are ways to handle it, but how is unique to each application. There’s no generally applicable solution for all applications. Other than “Don’t do that”.

How hard can it be? Hard enough for any single app. Across the spectrum of apps on Windows? Very.

One size can’t fit all, so MSIX offers several options.

Default Behavior: Fail with ERROR_PACKAGES_IN_USE

In the simplest case, Deployment rejects a request to service a package while in use. For example, assume Contoso.PointOfSale-v1.msix declares an application using Contoso.PointOfSale.exe. The application is running. A deployment request to update the package to v2 will detect the Contoso.PointOfSale.exe process is using the v1 package and fail the request e.g.

Add-AppxPackage 'C:\Packages\Downloads\Contoso.PointOfSale-v2.msix'
...
Add-AppxPackage : Deployment failed with HRESULT: 0x80073D02, The package could not be installed because resources it modifies are currently in use.
...

Deployment returns ERROR_PACKAGES_IN_USE (0x80073D02), indicating the deployment operation cannot proceed because it would service a package while in use.

Option 1: Shut Down the Application

One option is to quit the app using the v1 package to unblock the update.

Another option is to terminate the app via TerminateProcess(), TASKKILL, PowerShell cmdlets or similar utilities.

PackageManager provides an option to do exactly this: ForceTargetAppShutdown.

var packageUri = new Uri("C:\\Packages\\Contoso.PointOfSale-v2.msix");
var options = new AddPackageOptions();
options.ForceTargetAppShutdown = true;
var packageManager = new PackageManager();
var result = await packageManager.AddPackageByUriAsync(packageUri, options);

Or use the similarly named -ForceTargetApplicationShutdown option with the Add-AppxPackage PowerShell cmdlet:

Add-AppxPackage 'C:\Packages\Contoso.PointOfSale-v2.msix' -ForceTargetApplicationShutdown

This deployment request checks for processes using the target package. It shuts them down, forcibly if necessary, to unblock the deployment operation.1

Option 2: Defer the Update

Failure and TerminateProcess() are rather stark options. Not every process can quit or be terminated harmlessly. For example, it would be disruptive if Terminal is running a batch job that takes hours to complete.

MSIX offers an opt-in solution in AppxManifest.xml: defer</>.

When a package sets uap17:UpdateWhileInUse2 to defer, Windows defers the update rather than shutting down the application. This also takes precedence over force-update options such as ForceTargetAppShutdown: Windows ignores those options for a package that declares deferred update behavior. Windows defers the update until the package is no longer in use. Deployment completes it at the next opportunity.

Alternatively, deferred registration can be requested at runtime for an individual deployment operation via DeferRegistrationWhenPackagesAreInUse. If a package is currently in use, registration is delayed and completed when the package can be updated, such as on the application’s next activation.

For example, using the PackageManager API:

var packageUri = new Uri("C:\\Packages\\Contoso.PointOfSale-v2.msix");
var options = new AddPackageOptions();
options.DeferRegistrationWhenPackagesAreInUse = true;
var packageManager = new PackageManager();
var result = await packageManager.AddPackageByUriAsync(packageUri, options);

or the Add-AppxPackage PowerShell cmdlet:

Add-AppxPackage 'C:\Packages\Contoso.PointOfSale-v2.msix' -DeferRegistrationWhenPackagesAreInUse

Many apps, packaged and unpackaged, offer this sort of update experience. When an update is available, the app offers an ‘Update now’ option: “Hey buddy, I’ve got an update. If you want it now, great. If not, I’ll take care of it later when you’re not using me.”

This gives developers two ways to request deferred updates: a package can opt in to the behavior through its manifest, or an individual deployment request can opt in through an API or tool.

Detect a Deferred Update

Can you detect if a package has an update deferred?

Yes!

PackageDeploymentManager.IsPackageRegistrationPending returns true if the package family has a pending (previously deferred) update for the current user.

PackageDeploymentManager.IsPackageRegistrationPendingForUser returns true if the package family has a pending (previously deferred) update for the specified user. As usual, admin privilege is required if the specified user isn’t the caller.

Defer Removal While In Use

Remove operations implicitly have ‘Force’ semantics so they have no explicit [ForceTargetApplicationShutdown] option.

But what if an application is busy?

MSIX offers similar deferred behavior for removal via PackageManager.RemovePackageAsync(packageFullName, RemovalOptions.DeferRemovalWhenPackagesAreInUse):

var packageManager = new PackageManager();
string packageFullName = "Contoso.PointOfSale_2.3.4.5_arm64__1234567890abc";
var options = RemovalOptions.DeferRemovalWhenPackagesAreInUse;
var result = await packageManager.RemovePackageAsync(packageFullName, options);

If the package is in use, Deployment marks it for removal at the next opportunity3 instead of terminating processes to unblock the removal. The algorithm is effectively:

IF package is in use
    IF options.DeferRemovalWhenPackagesAreInUse is set
        Mark the package for deferred removal
        return SUCCESS
    ELSE
        Ask app to shutdown
        IF app still running
            TerminateProcess()
        ENDIF
        IF app still running
            return ERROR_PACKAGES_IN_USE
        ENDIF
    ENDIF
ENDIF

// package is not in use
Remove the package
return SUCCESS

1 Processes are requested to shut down and, if necessary, may be forcibly terminated via TerminateProcess().

2 uap17:UpdateWhileInUse requires Windows 11 version 24H2 (build 26100) or later.

3 Deployment completes a deferred removal when it gets an opportunity after the package is no longer in use. Depending on how the package is used, that may not occur until a later user session.

Author

Howard Kapustein
Principal Software Engineer

MSIX Development Engineer/Architect

0 comments