Add public-API packaged-app identity/AUMID groundwork and Windows gating to PackagedApp extension#9914
Add public-API packaged-app identity/AUMID groundwork and Windows gating to PackagedApp extension#9914Evangelink wants to merge 1 commit into
Conversation
The PackagedApp launcher's only real launch path was CopyDirectory + Process.Start, which cannot launch a packaged (MSIX) WinUI/UWP app; VSTest gets registration + AUMID activation from VS-internal deployment components (IVsAppContainerProjectDeploy2, IDeploymentServicesProvider) that are not redistributable. This adds the parts that need no VS-internal API: - AppxManifestInfo: parses AppxManifest.xml and computes PackageFamilyName + Application User Model ID using the public Windows publisher-hash algorithm (SHA-256 of the UTF-16LE publisher, first 8 bytes, Crockford base32). Pure managed, cross-platform, unit-tested against the well-known 8wekyb3d8bbwe vector. - IsEnabledAsync now gates on OperatingSystem.IsWindows(), so on non-Windows the launcher is never registered and the platform keeps its default in-process path (instead of being forced onto the controller/deploy path). - LaunchTestHostAsync now detects a packaged layout (AppxManifest.xml) and fails fast with an actionable message including the AUMID activation would use, referencing #2784, instead of silently starting an executable that cannot host the run. Non-packaged (loose-layout) hosts keep the existing Process.Start path. Registration (PackageManager.RegisterPackageByUriAsync) + AUMID activation (IApplicationActivationManager) and the sandbox connect-back transport remain a follow-up (#2784). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5c7d634-e822-4475-9312-a9dde92753f6
There was a problem hiding this comment.
Pull request overview
This PR adds groundwork in the Microsoft.Testing.Extensions.PackagedApp extension to recognize packaged (MSIX) layouts by parsing AppxManifest.xml to compute PFN/AUMID, gates the extension to Windows-only registration, and fails fast with an actionable error when a packaged layout is detected (since AUMID activation isn’t implemented yet).
Changes:
- Add
AppxManifestInfoto parseAppxManifest.xmland computePackageFamilyNameandAppUserModelId(AUMID), plus unit tests for the publisher-hash algorithm and manifest parsing. - Gate
PackagedAppTestHostLauncher.IsEnabledAsync()toOperatingSystem.IsWindows()and reject packaged layouts (manifest present) with a localized, actionable error. - Update resources (
.resx+.xlf) and internal API tracking; expose internals to the unit test assembly.
Show a summary per file
| File | Description |
|---|---|
| test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj | Conditionally reference the PackagedApp extension only for .NETCoreApp TFMs. |
| test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AppxManifestInfoTests.cs | New unit tests covering publisher-id hashing and manifest parsing edge cases. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/AppxManifestInfo.cs | New manifest parser + PFN/AUMID computation. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackagedAppTestHostLauncher.cs | Windows gating + fail-fast rejection for packaged layouts; updated doc remarks. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/ExtensionResources.resx | Add new localized strings for invalid manifest and unsupported packaged launch. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.cs.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.de.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.es.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.fr.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.it.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ja.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ko.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.pl.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.pt-BR.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ru.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.tr.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.zh-Hans.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.zh-Hant.xlf | Add new trans-units for the new resource keys. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/Microsoft.Testing.Extensions.PackagedApp.csproj | Add InternalsVisibleTo for the unit test assembly. |
| src/Platform/Microsoft.Testing.Extensions.PackagedApp/InternalAPI/InternalAPI.Unshipped.txt | Track newly introduced internal API surface for AppxManifestInfo. |
Review details
- Files reviewed: 20/20 changed files
- Comments generated: 3
- Review effort level: Low
| info = ReadFromManifest(manifestPath); | ||
| return true; |
| // Packaged Windows apps (UWP/WinUI) are a Windows-only concept. On other operating systems the | ||
| // launcher stays disabled so it is never registered, which keeps the platform on its default | ||
| // in-process/Process.Start path instead of forcing the controller (deploy-and-launch) host. | ||
| public Task<bool> IsEnabledAsync() => Task.FromResult(OperatingSystem.IsWindows()); |
| if (AppxManifestInfo.TryReadFromLayout(sourceDirectory, out AppxManifestInfo? manifestInfo)) | ||
| { | ||
| throw new InvalidOperationException( | ||
| string.Format( | ||
| CultureInfo.InvariantCulture, |
🧪 Test quality grade — PR #9914
This advisory comment was generated automatically. Grades are heuristic Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
Summary
Follow-up to the discussion under #9908 about
Microsoft.Testing.Extensions.PackagedApp. Today the launcher's only real launch path isCopyDirectory+Process.Start, which cannot launch a packaged (MSIX) WinUI/UWP app. VSTest gets loose-layout registration and AUMID activation from Visual-Studio-internal deployment components (IVsAppContainerProjectDeploy2,IDeploymentServicesProvider.GetAppLauncher(), MEF-composed from the VS install) that are not redistributable, so a standalone MTP extension cannot depend on them.This PR lands the parts of that flow that need no VS-internal API, plus makes the extension honest about what it can do today.
Changes
AppxManifestInfo(new): parsesAppxManifest.xmland computes the PackageFamilyName and Application User Model ID ({PackageFamilyName}!{AppId}) using the public Windows publisher-hash algorithm — SHA-256 of the UTF-16LEPublisher, first 8 bytes, Crockford base32. Pure managed and cross-platform; this is the public replacement for VS's internaldeploymentFile.AppUserModelId. Unit-tested against the well-known8wekyb3d8bbwevector.IsEnabledAsync()now returnsOperatingSystem.IsWindows(). On non-Windows the launcher is never registered, so the platform keeps its default in-process path instead of being forced onto the controller/deploy path by a no-op launcher.LaunchTestHostAsyncdetects a packaged layout (presence ofAppxManifest.xml) and throws an actionable error — including the AUMID that activation would use and a pointer to Add support for testing unpackaged WinUI applications #2784 — instead of silentlyProcess.Starting an executable that can't host the run. Non-packaged (loose-layout) hosts keep the existing behavior unchanged.Still a follow-up (not in this PR — #2784)
Actual
PackageManager.RegisterPackageByUriAsyncregistration,IApplicationActivationManagerAUMID activation, and the AppContainer connect-back transport (the platform passes the controller IPC pipe name via an environment variable, which an activated packaged process does not inherit) remain to be done.Verification
Microsoft.Testing.Extensions.PackagedAppbuilds with 0 warnings / 0 errors (incl.-p:TreatWarningsAsErrors=true); internal API and xlf updated.AppxManifestInfoTests(12 tests) discovered and passing; fullMicrosoft.Testing.Extensions.UnitTestssuite green (640 passed, 4 skipped, 0 failed).