Skip to content

Fix PackagedApp registration when switching build layouts - #11372

Open
Sergio Pedri (Sergio0694) wants to merge 9 commits into
microsoft:mainfrom
Sergio0694:user/sergiopedri/packaged-layout-registration
Open

Sergio Pedri (Sergio0694) wants to merge 9 commits into
microsoft:mainfrom
Sergio0694:user/sergiopedri/packaged-layout-registration

Conversation

@Sergio0694

@Sergio0694 Sergio Pedri (Sergio0694) commented Sep 18, 2026

Copy link
Copy Markdown
Member

Summary

Fixes PackagedApp activating an older registered layout instead of the requested build when both layouts have the same package identity and version. DeploymentResult.IsRegistered alone does not guarantee that Windows registered the requested directory.

  • Verify the current user's main-package registration points to the requested manifest directory before activation.
  • If Windows retains a different development layout, remove that registration with PreserveApplicationData, register the requested layout again, and verify the result. Never remove a conflicting non-development registration or activate an unverified layout.
  • Validate that removal actually unregisters the stale package before attempting replacement.
  • Serialize registration through AUMID activation across processes. Cancellation observed before removal prevents destructive work; once removal completes, restore and verify the requested registration before surfacing cancellation.
  • Add regression coverage for same-version layout switches, repeated runs, normalized paths, registration/removal failures, ambiguous registrations, cancellation boundaries, and cross-process serialization. Update diagnostics, localization entries, and package documentation.

Related to #9933.

Validation

  • Focused registration, launcher, and manifest tests: 105 passed, 2 OS-specific skips.
  • Review follow-up PackagedApp test slice: 82 passed, 2 OS-specific skips.
  • All four PackagedApp target frameworks build without warnings or errors; changed C# files pass formatting and UTF-8 BOM verification.
  • Windows x64 reproduction: the original 2.4.1 launcher runs layout A when B is requested. With the fix, A-to-B, repeated B, and B-to-A runs execute the requested layout and retain a LocalState marker. An invalid manifest fails immediately without executing tests or losing application data.
  • Azure Pipelines build 1602057 contained no product test failures. Its Windows jobs stopped before build/test because the hosted agents lacked the expected LocalDumps registry key, and its macOS test step passed before the job hit the worker timeout. Follow-up commits trigger fresh CI runs.

All original validation above was performed by the parent session on exactly this fix. Temporary Windows registrations have been removed and the parent's worktree is clean.

Verify the current-user registration before activation, replace stale development registrations while preserving application data, and fail safely if the requested layout cannot be registered. Add regression coverage and update localized diagnostics and package documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 18, 2026 05:48
@Sergio0694
Sergio Pedri (Sergio0694) marked this pull request as ready for review September 18, 2026 05:49
@github-actions github-actions Bot added the state/needs-review Awaiting review from the team. label Sep 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The registration-to-activation sequence has an unresolved cross-process race in sensitive per-user Windows package state.

Pull request overview

Fixes PackagedApp layout switching by verifying Windows registration before AUMID activation.

Changes:

  • Re-registers stale development layouts while preserving application data.
  • Adds diagnostics, localization resources, documentation, API baselines, and regression tests.
File summaries
File Description
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/PackageDeployerTests.cs Tests registration and failure scenarios.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.zh-Hant.xlf Adds Traditional Chinese localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.zh-Hans.xlf Adds Simplified Chinese localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.tr.xlf Adds Turkish localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ru.xlf Adds Russian localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.pt-BR.xlf Adds Brazilian Portuguese localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.pl.xlf Adds Polish localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ko.xlf Adds Korean localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.ja.xlf Adds Japanese localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.it.xlf Adds Italian localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.fr.xlf Adds French localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.es.xlf Adds Spanish localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.de.xlf Adds German localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/xlf/ExtensionResources.cs.xlf Adds Czech localization entries.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/Resources/ExtensionResources.resx Defines new registration diagnostics.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/RegisteredPackageInfo.cs Models installed package registration details.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs Verifies and replaces stale registrations.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/PACKAGE.md Documents layout-switching behavior.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/InternalAPI/Windows/InternalAPI.Unshipped.txt Updates Windows internal API baseline.
src/Platform/Microsoft.Testing.Extensions.PackagedApp/InternalAPI/InternalAPI.Unshipped.txt Tracks shared internal APIs.
Review details
  • Files reviewed: 20/20 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026
@github-actions github-actions Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026
Hold a cancellable per-user, per-package-family file lease across registration, handoff creation, and AUMID activation. Add contention, cancellation, thread-switch, failure, and cross-process regression coverage, with related diagnostics and documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 18, 2026 06:44
@github-actions github-actions Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026
@github-actions github-actions Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Windows package lifecycle and cross-process synchronization changes require human review, with removal-state and cancellation handling still unresolved.

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs:77

  • ExtendedErrorCode only reports whether the removal operation completed successfully; DeploymentResult.IsRegistered reports whether the package remains registered. If removal returns S_OK but leaves the package registered, this code retries registration against the stale layout and later reports a location mismatch instead of the removal failure. Treat either a still-registered result or a negative HRESULT as removal failure before retrying.
    src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs:105
  • Both registration queries have a cancellation gap. If the token is canceled while findRegisteredPackages() is running and that query returns an ambiguous, missing, or non-development registration, the following branch throws a wrapped deployment error before the later cancellation check runs. Check the token immediately after this query and after the retry query at line 132 so cancellation consistently propagates as OperationCanceledException.
  • Files reviewed: 23/23 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

This comment has been minimized.

Validate that stale registrations are actually removed and finish restoring the requested layout before propagating cancellation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 18, 2026 09:20
@github-actions github-actions Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026

@Evangelink Amaury Levé (Evangelink) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed an extensive lifecycle, concurrency, API-baseline, localization, and test-quality review. I found and fixed three additional correctness gaps in commit 98683104c:

  • A canceled token could be missed immediately after either package-registration query, causing a location or registration error to win over cancellation and potentially starting destructive removal.
  • A completed removal operation could still report the package as registered; replacement registration now refuses to proceed unless DeploymentResult.IsRegistered confirms removal.
  • Cancellation arriving after stale-registration removal could leave the package intentionally unregistered. Once removal starts successfully, the code now restores and verifies the requested layout before propagating cancellation.

The original cross-process registration-to-activation race is correctly addressed by the per-user, package-family file lease. I found no remaining actionable defects in the lock identity, lease lifetime, activation ordering, API baselines, generated XLF changes, or the changed tests.

CI build 1602057 had no product test failures: both Windows legs stopped before build/test because the hosted agents lacked the expected LocalDumps registry key, while the macOS test step passed before the job hit its worker timeout. A fresh build, 1602159, was queued by the follow-up commit.

Review coverage
  • Registration state transitions, same-version layout replacement, and non-development safeguards
  • Cross-process locking, case normalization, cancellation, failure cleanup, and activation ordering
  • Windows deployment-result semantics and post-removal consistency
  • All four package target frameworks and internal API baselines
  • Resource diagnostics, generated localization files, package documentation, and UTF-8 BOM requirements
  • Changed-test isolation, deterministic synchronization, assertion relevance, negative paths, and cancellation boundaries
  • Azure Pipelines failure classification and correlation against the base-branch build

@microsoft-github-policy-service microsoft-github-policy-service Bot added state/needs-review Awaiting review from the team. and removed state/needs-review Awaiting review from the team. labels Sep 18, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 18, 2026
@github-actions github-actions Bot added state/approved Proposal approved; ready for implementation. and removed state/needs-review Awaiting review from the team. state/approved Proposal approved; ready for implementation. labels Sep 18, 2026
@github-actions

This comment has been minimized.

Hold a read-shared manifest lease throughout registration and activation, and use the same parsed identity for locking, verification, and the AUMID. Preserve safety-validation diagnostics by wrapping only deployment operation failures.

Confirm removal by querying current-user registrations: native RemovePackageAsync can report IsRegistered=true even after successful unregistration. Preserve the existing cancellation recovery and add manifest-race and diagnostic regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fresh Windows agents may not have the WER LocalDumps key. Create it only when absent before writing DumpFolder and DumpCount, preserving existing values and per-application settings. This fixes the pre-build Windows setup failure in build 1602221.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 18, 2026 20:50
auto-merge was automatically disabled September 18, 2026 20:50

Head branch was pushed to by a user without write access

@github-actions github-actions Bot added state/approved Proposal approved; ready for implementation. and removed state/approved Proposal approved; ready for implementation. labels Sep 18, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added state/needs-review Awaiting review from the team. labels Sep 18, 2026
@github-actions github-actions Bot added state/approved Proposal approved; ready for implementation. and removed state/needs-review Awaiting review from the team. state/approved Proposal approved; ready for implementation. labels Sep 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-process synchronization, destructive registration replacement, cancellation recovery, and an unresolved misleading failure path require human validation.

Review details
  • Files reviewed: 24/24 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 18, 2026
@github-actions github-actions Bot added state/approved Proposal approved; ready for implementation. and removed state/needs-review Awaiting review from the team. state/approved Proposal approved; ready for implementation. labels Sep 18, 2026
Limit the removal callback to the native deployment operation and verify current-user registration separately in the transaction. Preserve original lookup failures and cancellation recovery, and add regression coverage distinguishing removal errors from post-removal query errors.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 18, 2026 21:17
@github-actions github-actions Bot added state/approved Proposal approved; ready for implementation. and removed state/approved Proposal approved; ready for implementation. labels Sep 18, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the state/needs-review Awaiting review from the team. label Sep 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

OS-dependent registration mutation, cross-process locking, and cancellation recovery require final human validation.

Review details

Suppressed comments (1)

src/Platform/Microsoft.Testing.Extensions.PackagedApp/PackageDeployer.cs:193

  • A native removal failure is wrapped with PackagedAppRegistrationFailed, so an error such as “package is in use” is reported as “Failed to register” with Developer Mode remediation. This misidentifies the failed operation and can send users toward an unrelated fix. Use a removal-specific resource here, preserve the original exception as the inner exception, and regenerate the XLF files from the RESX entry.
        catch (Exception ex) when (ex is not OperationCanceledException)
        {
            throw CreateDeploymentFailureException(manifestPath, ex);
  • Files reviewed: 24/24 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

Copy link
Copy Markdown
Contributor

Preliminary test-triage analysis — Azure Pipelines build 1603070

Analysis mode: early (Windows Release build leg failed; other legs in the aggregate build may still be running).

Failing check: microsoft.testfx (Build Windows Release)
Affected leg: Windows Release, net462
Test: Microsoft.Testing.Platform.ServerMode.Client.Sources.UnitTestsMtpServerClientInProcessTests.Dispose_BlockedHandlersAndCallback_ReturnsWithinTheDocumentedBound

Failure signature:

Assertion failed. Expected value to be less than the upper bound.
Dispose took 10.0s; it must abandon an unresponsive application within the documented bound rather than block indefinitely.
upper bound: 00:00:09
actual:      00:00:10.0168380

Findings:

  • This is a timing-margin assertion (Assert.IsLessThan(TimeSpan.FromSeconds(9), stopwatch.Elapsed)), and the observed duration (10.02s) exceeded the 9s bound by ~1s.
  • The same test passed cleanly in three other legs of this same build: Linux Release net8.0 (6.16s), Windows Debug net8.0 (6.02s), Windows Debug net462 (6.02s), and Windows Release net8.0 (6.03s). Only the Windows Release net462 run showed the elevated ~10s duration, suggesting an isolated timing/load variance on that leg rather than a deterministic product regression.
  • No retry attempts were recorded for this test in the collected evidence (retryAttempts: []), so this is a single observed run, not a proven fail-then-pass flake.
  • Historical data is unavailable for this early analysis (history.json is intentionally empty in early mode), so I cannot compare against prior occurrences of this signature yet.
  • Ten crash/hang .dmp files were also collected from this build's Windows Release TestResults folder (e.g. UnhandledExceptionPolicyTests.exe, TestDiscoveryWarnings.exe, TrxTest.exe, DotnetTestPipeBaselineTest.exe, CtrfReportTest.exe, HtmlReportTest.exe), but none of them map to the failing test above, and the timeline shows only this one test failure plus the resulting non-zero exit code for the leg's Test task. No further crash/hang signal is currently associated with this specific failure.

Confidence: Low-to-moderate that this is a code defect. The evidence to date looks more consistent with an environment-specific timing margin issue (close to the 9s bound, isolated to one leg) than a deterministic regression, but this cannot be confirmed until the full build evidence and any retries are available.

Next step: Await the completed aggregate build. If this test fails again on Windows Release net462 (or elsewhere) with a similar or worse margin, or if history across subsequent builds shows a recurring pattern, that would support raising the assertion bound or investigating the Dispose abandon-timeout logic in MtpServerClientInProcessTests. A single near-miss on one leg does not yet meet the bar for a durable issue.

Note: other build legs may still be running; this preliminary analysis may be superseded by a final resolution comment once the aggregate build completes.

🤖 Automated content by GitHub Copilot. Generated by the Pipeline Test Triage workflow. · copilot · auto · 36.4 AIC · ⌖ 6.1 AIC · ⊞ 8.9K

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/approved Proposal approved; ready for implementation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants