Skip to content

Commit db01c42

Browse files
Grant identity: troubleshooting table, SEO aliases, error handling, feature list (#6648)
* Grant identity: troubleshooting table, SEO aliases, error handling, feature list - Add Troubleshooting section with error table (0x800B0109, 0x80073CF9, 0x80073D54, 0x80073CF6, identity-missing-at-runtime) + Event Viewer tip - Add inline 'what you unlock' lead-in at top of how-to page - Add sparse package / packaging with external location SEO aliases to keywords and intro paragraph - Add DeploymentResult.ExtendedErrorCode check to AddPackageByUriAsync snippet; clarify externalLocation must be absolute path - Expand feature list on modernize landing (push notifications, Windows AI APIs, share targets, etc.) in both table row and section prose - Add sparse package alias to modernize landing Features section Closes remaining gaps from ADO #568632. Co-authored-by: Copilot <[email protected]> * Fix ExtendedErrorCode check: compare to 0 (HRESULT), not null DeploymentResult.ExtendedErrorCode is an HRESULT int, not nullable. Check against 0 (S_OK) and format directly without .HResult property. Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent f84e16b commit db01c42

2 files changed

Lines changed: 30 additions & 8 deletions

File tree

hub/apps/desktop/modernize/grant-identity-to-nonpackaged-apps.md

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ title: Grant package identity by packaging with external location manually
33
description: Learn how to grant package identity to an unpackaged Win32 app so that you can use modern Windows features in that app.
44
ms.date: 04/08/2026
55
ms.topic: how-to
6-
keywords: windows 10, desktop, sparse, package, identity, external, location, MSIX, Win32
6+
keywords: windows 10, desktop, sparse package, packaging with external location, package identity, external location, MSIX, Win32, unpackaged app
77
ms.localizationpriority: medium
88
ms.custom: RS5
99
---
1010

1111
# Grant package identity by packaging with external location manually
1212

13-
For the motivations behind adding package identity, as well as the differences between building
13+
> **Why do this?** Granting your app a package identity (also called a *sparse package* or *packaging with external location*) unlocks Windows platform features that are otherwise unavailable to unpackaged apps: toast and push notifications, background tasks, app extensions, share targets, file associations, startup tasks, privacy consent prompts, and Windows AI Foundry APIs — all without switching to full MSIX packaging or changing your existing installer.
14+
15+
For more about the motivations behind adding package identity, as well as the differences between building
1416
identity packages in Visual Studio and building them manually, see
1517
[Overview](/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps-overview).
1618

@@ -264,7 +266,11 @@ var packageManager = new PackageManager();
264266
var options = new AddPackageOptions();
265267
options.ExternalLocationUri = externalUri;
266268

267-
await packageManager.AddPackageByUriAsync(packageUri, options);
269+
var result = await packageManager.AddPackageByUriAsync(packageUri, options);
270+
if (result.ExtendedErrorCode != 0)
271+
{
272+
throw new Exception($"Package registration failed: {result.ErrorText} (0x{result.ExtendedErrorCode:X8})");
273+
}
268274

269275
...
270276

@@ -280,13 +286,14 @@ foreach (var package in packages)
280286

281287
Note the below important details about this code:
282288

283-
* Set `externalLocation` to the absolute path of your application's installation directory
284-
(without any executable names)
285-
* Set `packagePath` to the absolute path of the signed identity package produced in the previous step
289+
* Set `externalLocation` to the **absolute path** of your application's installation directory
290+
(without any executable names). `new Uri(somePath)` produces a `file:///` URI as required by the API.
291+
* Set `packagePath` to the **absolute path** of the signed identity package produced in the previous step
286292
(with the file name)
287293
* The `<IdentityPackageFamilyName>` can be found by running the `Get-AppxPackage <IdentityPackageName>`
288294
PowerShell command on a system where the identity package is registered. The `PackageFamilyName` property
289295
contains the value to use here.
296+
* Check `result.ExtendedErrorCode` after registration to surface actionable error details. See [Troubleshooting](#troubleshooting) for common error codes.
290297

291298
#### Per-Machine (PackageManager)
292299

@@ -336,6 +343,21 @@ Note the below important details about this code:
336343
PowerShell command on a system where the identity package is registered. The `PackageFamilyName`
337344
property contains the value to use here.
338345

346+
## Troubleshooting
347+
348+
The table below lists the most common errors when registering an identity package and how to fix them.
349+
350+
| Error code | Symptom | Cause | Fix |
351+
|---|---|---|---|
352+
| `0x800B0109` / `CERT_E_UNTRUSTEDROOT` | `Add-AppxPackage` or `AddPackageByUriAsync` fails immediately | Self-signed certificate is not in the **Trusted People** store | Follow the [cert trust step](#build-and-sign-the-identity-package) above to import the public `.cer` into `Cert:\CurrentUser\TrustedPeople` |
353+
| `0x80073CF9` | Registration fails with "version already registered" | The exact same package version is already registered on this machine | Unregister the existing package first (`Remove-AppxPackage` or `RemovePackageAsync`), then re-register |
354+
| `0x80073D54` | Registration succeeds but identity is missing at runtime | `publisher`, `packageName`, or `applicationId` in the app's side-by-side manifest (`msix` element) don't match the identity package manifest | Ensure `Publisher`/`Name`/`Application Id` are identical in both manifests — see [Add identity metadata](#add-identity-metadata-to-your-desktop-application-manifests) |
355+
| Identity absent at runtime (no error) | `Package.Current` is null or `GetPackage()` returns nothing | The `ExternalLocation` path passed at registration doesn't match the directory where the app actually runs | Verify the absolute path passed as `ExternalLocation` is exactly the app's install directory |
356+
| `0x80073CF6` | Registration fails with "manifest invalid" | Manifest XML is malformed or a required attribute is missing | Validate the manifest with `MakeAppx.exe pack` — it reports schema errors. Ensure `uap10:AllowExternalContent` is `true` and `runFullTrust` capability is declared |
357+
358+
> [!TIP]
359+
> For richer diagnostics, check the Windows **Event Viewer** under **Applications and Services Logs > Microsoft > Windows > AppxDeployment-Server**. It logs the full deployment error with context that isn't always surfaced in the API result or PowerShell output.
360+
339361
## Sample apps
340362

341363
See the [PackageWithExternalLocation](https://aka.ms/sparsepkgsample) samples for fully functional

hub/apps/desktop/modernize/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Use the table below to find the right starting point for your situation.
1919
| Add modern UI controls (Fluent, rounded corners, dark mode) to my WPF or Win32 app | [Host WinUI controls in a WPF app (XAML Islands)](xaml-islands/xaml-islands.md) |
2020
| Use Windows platform features (notifications, sharing, file pickers) in my WPF or WinForms app | [Call Windows Runtime APIs in desktop apps](desktop-to-uwp-enhance.md) |
2121
| Package my app for the Microsoft Store or enterprise deployment | [Package a desktop app with MSIX](/windows/msix/desktop/source-code-overview) |
22-
| Unlock features that require package identity (background tasks, app extensions) | [Grant identity to an unpackaged app](grant-identity-to-nonpackaged-apps-overview.md) |
22+
| Unlock features that require package identity (push notifications, background tasks, app extensions, Windows AI APIs, share targets, and more) | [Grant identity to an unpackaged app](grant-identity-to-nonpackaged-apps-overview.md) |
2323
| Integrate my app with Windows 11 shell features (snap layouts, context menus, taskbar) | [Integrate with Windows 11 features](desktop-to-uwp-extensions.md) |
2424
| Move to a fully modern app with WinUI 3 over time | [Migrate to WinUI 3](../../winui/winui3/create-your-first-winui3-app.md) |
2525
| Add on-device AI capabilities to my desktop app | [Windows AI Foundry](/windows/ai/overview) |
@@ -50,7 +50,7 @@ For more information, see [Building an MSIX package from your code](/windows/msi
5050

5151
## Features that require package identity
5252

53-
Some Windows platform features — including certain background tasks, app extensions, and sharing targets — require your app to have a [package identity](/uwp/schemas/appxpackage/uapmanifestschema/element-identity) at runtime. You can grant identity to an unpackaged app without full MSIX packaging.
53+
Some Windows platform features — including push notifications, background tasks, app extensions, sharing targets, Windows AI Foundry APIs, file associations, and startup tasks — require your app to have a [package identity](/uwp/schemas/appxpackage/uapmanifestschema/element-identity) at runtime. You can grant identity to an unpackaged app without full MSIX packaging. This approach is sometimes called a *sparse package* or *packaging with external location*.
5454

5555
For more information, see:
5656
- [Package identity overview](package-identity-overview.md)

0 commit comments

Comments
 (0)