Skip to content

fix: Escape no longer stops an uninstall or a System Fixes repair half-way, and Uninstaller's Cancel stops a batch between apps - #2941

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/escape-never-stops-an-uninstall-or-repair
Oct 21, 2026
Merged

laurentiu021 merged 1 commit into
mainfrom
fix/escape-never-stops-an-uninstall-or-repair

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

Part 3 of #2834 for Uninstaller and System Fixes.

Confirmed in the code: Uninstaller passed the batch's own token to UninstallAsync and UninstallLocalAsync, so Cancel, and Escape while the batch ran, cancelled the running uninstaller, and RunProcessAsync and RunProcessWithShellAsync answer a cancel by ending its process tree. System Fixes' EscapeCancel returned CancelCommand whenever IsBusy was set, and every run on that tab changes Windows: SFC, DISM /RestoreHealth, the Windows Update reset and the WinGet reinstall.

The issue proposed that Escape stop only a read-only scan on both tabs. EveryCancellableTab_LetsEscapeReachItsOwnCancelCommand holds Escape and a tab's Cancel button to the same flag, so I took a different way on each:

  • Uninstaller: the uninstaller running now gets a token of its own, which only Dispose cancels, so closing SysManager still ends it after asking, as before. Cancel and Escape stop the batch before its next app instead, and while the running uninstaller finishes the status line says "Stopping after X. Its uninstaller finishes first, so it is not left half-removed.". An uninstaller with a window of its own can still be cancelled in that window. Escape and the button keep following IsBusy, and on a scan both stop the scan as before.
  • System Fixes: no EscapeCancel override, so Escape stops nothing on the tab. Its Cancel button still stops a repair, for a stop that is meant.
  • The guard: lists SystemFixesView as declining Escape, with the reason, requires its view model to override no EscapeCancel or one that returns null, and fails an entry whose view has no Cancel button any more.

The README's count of tabs Escape can cancel goes from 26 to 25, and the keyboard section says what Escape does on Windows Features, Uninstaller and System Fixes.

Still open on #2834: part 1 (naming and offering the parent features -All turns on) and part 5 (where the admin banner sits).

Docs

README: the keyboard section, Uninstaller and System Fixes. ARCHITECTURE: UninstallerViewModel and SystemFixesViewModel.

Tests

  • UninstallerViewModelTests: the cancel test now has three apps and cancels during the second, whose token is not cancelled; the line says it waits, the second finishes, the third never starts, and the batch reports "cancelled after 2/3 completed". New: Dispose still ends the running uninstaller. Both drain the batch in finally, so a failure cannot leave it holding the install lock for the next test.
  • SystemFixesViewModelTests: Escape is null while SFC runs, and the Cancel button still cancels it.
  • Red before the fix, green after, each undone on its own: the running uninstaller sharing the batch's token, Dispose sparing it (also caught by EveryDisposedCancellationSource_IsCancelledFirst), the waiting line, System Fixes answering Escape (also the README count), the guard without the exemption, and a stale exemption.
  • Run locally, twice: UninstallerViewModelTests, UninstallerViewModelGateTests, SystemFixesViewModelTests, ArchitectureTests, AcceleratorRoutingTests, ActivityLogServiceTests, SelectionSurvivesRescanGroupBTests, the four other Uninstaller classes, WingetFailureTests, InclusiveTermsTests and WindowsFeaturesTests (555), and the integration FilteredOutListViewUiTests (8). All four projects build with 0 warnings, and dotnet format --verify-no-changes is clean.

…f-way, and Uninstaller's Cancel stops a batch between apps

- UninstallerViewModel gives the uninstaller it runs a token of its own, which only Dispose cancels. Cancel and Escape
  stop a batch before its next app, after the running uninstaller has finished, and the status line says so. Both
  ended the running uninstaller, which can leave its program half-removed.
- SystemFixesViewModel overrides no EscapeCancel: every run on the tab changes Windows, and Escape ended SFC, DISM and
  the scripted repairs half-way. The Cancel button still stops one.
- EveryCancellableTab_LetsEscapeReachItsOwnCancelCommand lists System Fixes as declining Escape, with the reason, and
  fails an entry whose view has no Cancel button any more.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant