June 23rd, 2026
0 reactions

Add vs Stage and Register

Principal Software Engineer

As previously mentioned to ‘install’ a package, as people think of the term, Windows actually performs two separate operations: staging and registration.

To oversimplify:

  • Staging puts the package content on disk. At this point the package is present, but inert and unused.
  • Registering wires the package into a user’s profile. This includes creating tiles on the Start Menu, defining file type associations for the package’s applications and otherwise making the package available to the user.

One way to ‘install’ a package for a user is to explicitly stage it, then register the package:

var packageUri = new Uri("C:\\Packages\\ContosoParts-v1.2.3.4-x64.msix");
var stageOptions = new StagePackageOptions();
var packageManager = new PackageManager();
var stageResult = await packageManager.StagePackageByUriAsync(packageUri, stageOptions);
...
var packageFullName = "Contoso.Parts_1.2.3.4_x64__1234567890abc");
var registerOptions = DeploymentOptions.None;
var registerResult = await packageManager.RegisterPackageByFullNameAsync(packageFullName, null, registerOptions);
...

But this scenario is common enough that deployment handles it more efficiently as a single deployment operation: stage the package and register it in one request.

That’s what the ‘Add Package’ operation does:

var packageUri = new Uri("C:\\Packages\\ContosoParts-v1.2.3.4-x64.msix");
var options = new AddPackageOptions();
var packageManager = new PackageManager();
var result = await packageManager.AddPackageByUriAsync(packageUri, options);
...

AddPackage*() ensures the package is staged if necessary, then registers it for the user.

Why not always Add?

Because staging and registration have very different scopes.

A package is only staged once on a machine. Calling PackageManager.StagePackageAsync() multiple times only stages the package the first time. After that, deployment sees the package is already staged. Subsequent calls complete very quickly 🙂.

In practice, staging behaves like a per-machine operation. Multiple staging operations still result in only one copy of the package on disk.

On the other hand, registration is inherently per-user. A user cannot access a package unless it’s registered for that user.

An “Add Package” operation guarantees both staging and registration succeed together. That makes Add undesirable if you don’t want to register the package just yet.

For example:

  • You may want to stage and provision a package for all users without registering it for any specific user.
  • Or you may want to stage an update while connectivity is available, but delay registration until a later time when updating the package would not disrupt the user.

Likewise, sometimes you only need to register an already-staged package without performing any staging work — particularly if you no longer have access to the original .msix file needed for AddPackageAsync().

Author

Howard Kapustein
Principal Software Engineer

MSIX Development Engineer/Architect

0 comments