Skip to content

fix(cua-driver): uninstall.ps1 halts when scheduled task already gone - #1633

Merged
f-trycua merged 1 commit into
mainfrom
fix/uninstall-ps1-erroraction-on-missing-task
May 21, 2026
Merged

fix(cua-driver): uninstall.ps1 halts when scheduled task already gone#1633
f-trycua merged 1 commit into
mainfrom
fix/uninstall-ps1-erroraction-on-missing-task

Conversation

@f-trycua

@f-trycua f-trycua commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

Under \$ErrorActionPreference = 'Stop' (set at uninstall.ps1:57), PowerShell 5.1 treats native-command stderr as a terminating error. 2>\$null masks the display but the error record still trips Stop and halts the script. Net effect: when the `cua-driver-serve` Scheduled Task is already gone (e.g. installer's autostart step failed earlier), `schtasks /Query` writes "task not found" to stderr, the script terminates, and phases 2-5 (kill daemon, remove junctions, remove package home) all skip.

Fix

Locally lower `$ErrorActionPreference` to `Continue` around both `schtasks` invocations (Query and Delete), restore via `finally`. Missing-task detection still uses `$LASTEXITCODE` — same control flow.

Repro

# As cuademo (a standard admin user, NOT RID-500):
irm install.ps1 | iex                     # install OK
cua-driver autostart enable               # access-denied — task NOT registered
irm uninstall.ps1 | iex                   # ❌ halts at schtasks /Query

After this patch the uninstall completes cleanly through all 5 phases.

Related

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling in the driver uninstall process to ensure scheduled tasks are reliably removed during uninstallation.

Review Change Stack

…ound

Under $ErrorActionPreference = "Stop" (set at uninstall.ps1:57), PowerShell
5.1 treats native command stderr as a terminating error. `2>$null` masks
the display but the error record is still emitted into the error stream,
which trips the Stop preference and halts the script.

Repro: uninstall.ps1 on a host where the cua-driver-serve task was never
registered (e.g. install completed but `autostart enable` failed before
task creation, or a manual install that skipped autostart). Symptom:

  schtasks.exe : ERROR: The system cannot find the file specified.
  At line:147 char:14
  ...
  FullyQualifiedErrorId : NativeCommandError

Subsequent phases (kill running daemon, remove junctions, remove package
home) are then skipped because the script terminated early.

Fix: locally set $ErrorActionPreference = "Continue" around both schtasks
invocations (Query and Delete), restore in a finally block. The missing-
task case is detected via $LASTEXITCODE, same control flow as before.

Surfaced during the cuademo fresh-install dogfood after the cuademo-side
`cua-driver autostart enable` hit access-denied (no autostart task was
registered), then uninstall.ps1 couldn't tear down the partial install.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@vercel

vercel Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview May 21, 2026 4:47pm

Request Review

@f-trycua
f-trycua merged commit 46f0203 into main May 21, 2026
5 of 7 checks passed
@f-trycua
f-trycua deleted the fix/uninstall-ps1-erroraction-on-missing-task branch May 21, 2026 16:47
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a4f4f50-a116-40e1-8195-ba6fe25dfa55

📥 Commits

Reviewing files that changed from the base of the PR and between 6fe3931 and 182d04f.

📒 Files selected for processing (1)
  • libs/cua-driver/scripts/uninstall.ps1

📝 Walkthrough

Walkthrough

The PR refactors scheduled task removal in a PowerShell uninstall script to safely handle native command errors. The code wraps schtasks.exe calls in try/finally blocks that temporarily set $ErrorActionPreference = 'Continue', capturing query and delete exit codes for safe error reporting without terminating the script unexpectedly.

Changes

Scheduled Task Removal Error Handling

Layer / File(s) Summary
Task removal error handling with exit code capture
libs/cua-driver/scripts/uninstall.ps1
schtasks.exe /Query and /Delete calls are wrapped with $ErrorActionPreference = 'Continue' to capture exit codes into $taskExitCode and $delExit. This prevents missing-task stderr behavior from terminating execution under the script's default $ErrorActionPreference = "Stop". The delete warning path now reports the actual delete exit code instead of $LASTEXITCODE. Control flow for task presence checks, deletion confirmation, and success/warning/skip messaging remains unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

A rabbit hops through error codes with care, 🐰
No more crashes when tasks disappear into air,
Exit codes captured in variables so neat,
Makes uninstalls safe and complete!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/uninstall-ps1-erroraction-on-missing-task

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

f-trycua added a commit that referenced this pull request May 21, 2026
…rs → Cua\cua-driver, with auto-migration (#1644)

User-facing install paths drop the GitHub org prefix + Rust-port suffix:

  %LOCALAPPDATA%\Programs\trycua\cua-driver-rs\bin  →  Cua\cua-driver\bin
  %USERPROFILE%\.cua-driver-rs\                     →  .cua-driver\

Rationale:
- The Rust port IS the canonical Windows driver — there's no Swift
  Windows binary it's coexisting with anymore. The `-rs` suffix was
  the disambiguator while the Swift driver still shipped Windows
  binaries; it doesn't anymore, so the suffix is dead weight.
- `trycua` is the GitHub org prefix that doesn't belong in
  %LOCALAPPDATA%\Programs — vendor folders there are conventionally
  PascalCase company names (Microsoft\, Google\, NVIDIA\, ...).
  `Cua\` matches that convention.

## Auto-migration

install.ps1 detects the v0.2.13-and-earlier layout (when default paths
are in use, i.e. no $env:CUA_DRIVER_RS_INSTALL_DIR or
$env:CUA_DRIVER_RS_HOME override) and migrates transparently before
laying down the new install:

  1. Stop any cua-driver / cua-driver-uia daemon pinning legacy binary
     files open.
  2. Unregister the cua-driver-serve Scheduled Task (idempotent; uses
     the same defensive $ErrorActionPreference handling as
     uninstall.ps1's #1633 fix).
  3. Remove the legacy visible bin junction + empty parent dirs
     (cua-driver-rs\ and trycua\ when the latter is empty after the
     pass — vendor dir is preserved if other apps live under it).
  4. Remove the legacy package home tree (.cua-driver-rs\).
  5. Prune the legacy bin path from User PATH (the new install adds
     the new path; without pruning we'd accumulate stale PATH entries
     on every upgrade).

uninstall.ps1 always sweeps legacy paths too, so a single
`irm uninstall.ps1 | iex` leaves nothing behind even when run AFTER
the user has already upgraded to the new layout.

## Env var names unchanged

$env:CUA_DRIVER_RS_INSTALL_DIR and $env:CUA_DRIVER_RS_HOME keep the
`_RS_` infix even though the underlying paths are renamed. Changing
env var names silently would break existing automation (CI, devx
scripts, dotfiles) that pins a custom install dir.

## Compat

- v0.2.13 → v0.2.14 upgrade via `irm install.ps1 | iex`: transparent
  one-shot migration.
- Fresh v0.2.14 install: new paths only, no legacy detection needed.
- User with $env:CUA_DRIVER_RS_INSTALL_DIR or _HOME set: their
  override wins; legacy migration skipped to avoid surprising them.
- Crate names (cua-driver, cua-driver-rs), release tag prefix
  (cua-driver-rs-v0.2.x), CD asset filenames, binary names
  (cua-driver.exe), Scheduled Task name (cua-driver-serve), and named
  pipe (\\.\pipe\cua-driver) are all unchanged — only the user-facing
  install paths move.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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