Skip to content

fix: windows in-app uninstall fully wipes the data root (temp-copy cleaner)#323

Merged
bilbospocketses merged 12 commits into
mainfrom
fix-windows-uninstall-wipe-self-deletion
Jun 9, 2026
Merged

fix: windows in-app uninstall fully wipes the data root (temp-copy cleaner)#323
bilbospocketses merged 12 commits into
mainfrom
fix-windows-uninstall-wipe-self-deletion

Conversation

@bilbospocketses

Copy link
Copy Markdown
Owner

What & why

beta.51 shipped the first in-app Windows uninstall, but its cleanup helper runs from inside the data root it deletes (%ProgramData%\WsScrcpyWeb\control\operation-server\ws-scrcpy-web-launcher.exe). On a wipe (unchecking "keep my settings & logs") that left the data root behind, via three mechanisms:

  1. Windows won't delete a running executable image.
  2. The helper's working directory pinned the tree.
  3. log::append() does create_dir_all(<dataRoot>/logs) on every line, so the helper's own logging recreated logs/ right after deleting it.

The fix — two-phase temp-copy cleaner

All inside the Rust launcher; ServiceApi.ts is unchanged.

  • Phase 1 (run_bootstrap, the helper the server already spawns): resolve the context-appropriate temp dir (GetTempPath2W → user temp under a user token, hardened system temp under SYSTEM), copy the launcher there, spawn that copy detached (DETACHED_PROCESS | CREATE_NO_WINDOW, null stdio) with --wait-pid <self> --no-log + the uninstall params, then exit — releasing the running-exe lock. Falls back to the old in-place path if temp/copy/spawn fails.
  • Phase 2 (run_cleaner, the temp copy): logging disabled at process entry (--no-log), wait for the original to exit, run Update.exe --uninstall, then delete the data-root targets with a bounded retry. It then just lives in temp.

All three orphan mechanisms close: the deleter runs from temp, its CWD is temp, and it never logs into the data root. --keep still preserves config.json + logs.

Also in here

  • Smoke docs: bumped the target tag to v0.1.30-beta.52 (it was stale at beta.50) and added the missing Windows in-app-uninstall batch (#16) to the checklist.
  • Spec + plan: docs/specs/2026-06-08-windows-uninstall-wipe-self-deletion-design.md, docs/plans/2026-06-08-windows-uninstall-wipe-self-deletion.md.

Verification

  • cargo test: launcher 115, common 49, tray 4 — all green. cargo clippy --all-targets -- -D warnings clean. Full workspace builds on native Windows, so the #[cfg(windows)] paths type-check against windows 0.58.
  • Independent review pass — two important findings fixed (--no-log wired at main() entry; detached-spawn idiom), verdict APPROVE.
  • Runtime is VM-gated: the actual wipe-leaves-nothing behavior can only be confirmed on the Win11 snapshot (smoke 15.1/15.2), not on a dev box. That smoke is the gate to 0.1.30.

Test plan

  • Win11 VM — in-app uninstall keep (15.1): Program Files / service / tray / ARP gone; config.json + logs survive; reinstall reuses the port
  • Win11 VM — in-app uninstall wipe (15.2): the whole %ProgramData%\WsScrcpyWeb is gone, including control\operation-server\ (no leftover)

Two-phase temp-copy cleaner: the originally-spawned helper copies itself to
the context-appropriate OS temp dir (GetTempPath2W), spawns the copy detached
with --no-log + --wait-pid, and exits; the temp copy waits for the original to
exit, runs Update.exe --uninstall, then removes the dataRoot targets with a
bounded retry. Closes the three --wipe leftover mechanisms (running-exe lock,
CWD lock, log-dir recreation). Target: v0.1.30-beta.52.
- Honor --no-log at main() entry so the cleaner is silent from its first
  instruction (was only disabling inside run_cleaner, after main()'s preamble
  had already recreated <dataRoot>/logs — the --no-log flag was inert).
- Match the proven detached-survival idiom (DETACHED_PROCESS | CREATE_NO_WINDOW
  + null stdio) for the cleaner spawn, so it reliably outlives the bootstrapper.
- resolve_temp_dir: fail closed on a 0 / buffer-too-small GetTempPath return
  instead of risking an out-of-bounds slice (panic=abort) on the wipe path.
@bilbospocketses bilbospocketses added the release:beta Auto-release: bump to next beta on merge label Jun 9, 2026
@bilbospocketses bilbospocketses merged commit 10f6697 into main Jun 9, 2026
9 checks passed
@bilbospocketses bilbospocketses deleted the fix-windows-uninstall-wipe-self-deletion branch June 9, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:beta Auto-release: bump to next beta on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant