Repository navigation
Refuse Windows uninstall while GraphCode runs and make removal all-or-nothing - #662
Merged
Merged
Conversation
…-nothing Uninstall removed the scheduled task, Start-menu shortcut and PATH entry and then failed deleting the install root because live zmx session hosts held bin\zmx.exe, leaving a partial installation (Dev Box D10, 0.1.78-windows.beta17). Uninstall now refuses up front, changing nothing, while any process other than the managed daemon runs from the install root, naming each process and PID and how to end the sessions. After stopping the daemon it re-checks, probes every installed file for exclusive access, and renames the whole root aside in one step before removing integration; any failure moves it back, restores PATH and the shortcut, and restarts the daemon. User data preservation is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Colin Neilens <coneilen@microsoft.com>
This was referenced Oct 8, 2026
coneilen
added a commit
that referenced
this pull request
Oct 9, 2026
Record the 0.1.78-windows.beta18 candidate at 880e6a3 (#662-#665), its local validation, package, custody and Dev Box handoff identities, and the 57/41 parity count. Move beta17 to history. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Colin Neilens <coneilen@microsoft.com>
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Dev Box qualification of
0.1.78-windows.beta17(D10 Lifecycle) ranGraphCode-Setup.ps1 -Command Uninstallwhile 13 loopzmx.exesession hosts were running from the installedbin. Uninstall removed the scheduled task, Start-menu shortcut and user PATH entry, then failed (exit 1) atRemove-Item $InstallRoot -Recurse -ForcewithAccess to the path '...\current\bin\zmx.exe' is denied, leaving a partial installation of 13 files. This PR makes Windows uninstall all-or-nothing: it refuses up front, without changing anything, while GraphCode processes run from the install root, and it rolls back fully if removal fails after that point.Changes
PackageRuntime.ps1Uninstall-Package(also embedded verbatim in the generatedGraphCode-Setup.ps1):zmx.exe), the shell and the CLI are the user's live work, so Uninstall does not kill them. It exits 1 withUninstall changed nothing, names each process and PID, and says how to end the sessions (zmx.exe ls, thenzmx.exe kill NAME) and to rerun from a terminal outside GraphCode. The managed daemon is still stopped automatically. With-NoScheduledTask, a runninggraphcoded.exealso blocks..GraphCode-uninstall-<guid>in one step, and only then removes the task, PATH and shortcut. Any failure up to that point moves the root back, restores PATH and the shortcut (snapshot in%TEMP%), and restarts the daemon if it was running. The renamed tree is deleted last. If a file is opened in that short window, Uninstall still succeeds and warns with the leftover path..exeinside it is running, so the rename alone can't guard against live session hosts. That's why the process check is there. An exclusiveReadWriteopen does fail for running images and open handles.-RemoveUserData.Tools/windows/Tests/Packaging.Uninstall.Tests.ps1(4 cases), registered invalidate.ps1 -Task packagingcontracts and guarded inValidationRunner.Tests.ps1:live-session: a real process launched from the fixture's installedbin\zmx.exe(a copy ofPING.EXE) is running. Uninstall must refuse, namezmx.exeand its PID, leave the install tree, task, PATH, shortcut and daemon untouched, and leave the session alive.locked-file:bin\_FoundationICU.dllis held open by another process. Uninstall must refuse, report the file, leave everything intact and restart the daemon.task-removal-failure: failure is injected after the rename. The install must be restored byte-for-byte and the daemon restarted.success: everything is removed, no transaction debris is left, and user data is byte-identical.APPDATA) and processes are real.PACKAGING.mddocuments the behavior.validation-matrix.mdlists the new contract.Test plan
RED: git stash push -- Tools/windows/PackageRuntime.ps1; pwsh -NoProfile -File Tools\windows\Tests\Packaging.Uninstall.Tests.ps1 -> exit 1, live-session: left a partial installation: Access to the path '...\live-session\GraphCode\current\bin\zmx.exe' is denied. locked-file: left a partial installation: The process cannot access the file '...\bin_FoundationICU.dll' because it is being used by another process. task-removal-failure: left the daemon stopped after refusing
GREEN: pwsh -NoProfile -File Tools\windows\Tests\Packaging.Uninstall.Tests.ps1 -> Uninstall live-session refusal and all-or-nothing removal contracts (4 cases): PASS, exit 0 (also PASS under powershell.exe 5.1)
REGRESSION: pwsh -NoProfile -File Tools\windows\validate.ps1 -Task packaging -PackagingPart contracts -> exit 0, all contracts PASS incl. rollback, scheduler, signing and standalone setup executed=18; pwsh -NoProfile -File Tools\windows\Tests\ValidationRunner.Tests.ps1 -> ValidationRunner.Tests.ps1: PASS
What these runs did not cover:
-PackagingPart real:Packaging.Tests.ps1plusPackaging.RealLifecycle.Tests.ps1, which covers real scheduled-task self-uninstall) locally. It rebuilds the shared provider trees. This PR's Windows packaging CI job covers it.GraphCode-Setup.ps1with real loop zmx sessions.Checklist
git commit -s) per the DCOmake test): macOS only, not applicable to this Windows packaging change and not runmake check): macOS Swift lint, not run, and no Swift changedPackageRuntime.ps1fromHEAD(stashed), as recorded above