Skip to content

fix(autostart): hide console window at logon via PowerShell wrapper - #1654

Merged
f-trycua merged 1 commit into
trycua:mainfrom
hippoley:fix/autostart-windows-hidden-console
May 22, 2026
Merged

fix(autostart): hide console window at logon via PowerShell wrapper#1654
f-trycua merged 1 commit into
trycua:mainfrom
hippoley:fix/autostart-windows-hidden-console

Conversation

@hippoley

@hippoley hippoley commented May 22, 2026

Copy link
Copy Markdown
Contributor

Problem

The cua-driver-serve Scheduled Task launches a visible console window at every interactive logon (issue #1645). cua-driver.exe is a CUI binary — without a parent console, Task Scheduler allocates one and it stays on the desktop for the daemon lifetime.

Fix

Implement Option 2 from the issue: wrap the task action in a hidden PowerShell launcher.

Before:

Action: cua-driver.exe serve

After:

Action: powershell.exe -NoProfile -WindowStyle Hidden -NonInteractive
        -Command "Start-Process -FilePath <exe>
                  -ArgumentList 'serve' -WindowStyle Hidden
                  -WorkingDirectory <home>"

Start-Process -WindowStyle Hidden spawns the daemon fully detached. The powershell.exe wrapper exits immediately, leaving only cua-driver.exe in the process tree. No visible window, no flash.

Fixes #1645

Summary by CodeRabbit

  • Bug Fixes

    • Fixed the Windows autostart feature to launch the daemon silently without displaying a console window at user logon, improving startup experience.
  • Documentation

    • Updated documentation to explain the hidden-console startup behavior and resulting process tree management.

Review Change Stack

Fixes trycua#1645.

cua-driver.exe is a CUI (console-subsystem) binary. When Task Scheduler
launches it at logon without a parent console, Windows allocates a new
console window that stays visible on the desktop for the daemon lifetime.

Replace the direct task action with a PowerShell hidden wrapper:

  Before:
    Action: cua-driver.exe serve

  After:
    Action: powershell.exe -NoProfile -WindowStyle Hidden -NonInteractive
            -Command "Start-Process -FilePath <exe> -ArgumentList 'serve'
                      -WindowStyle Hidden -WorkingDirectory <home>"

Start-Process -WindowStyle Hidden spawns the daemon fully detached with
no visible window. The powershell.exe wrapper exits immediately after,
leaving only cua-driver.exe in the process tree. No flash, no console.
@vercel

vercel Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

@nishantpurohit04 is attempting to deploy a commit to the Cua Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR updates the Windows autostart registration script to hide the daemon console window on interactive logon. The scheduled task action is changed from launching cua-driver.exe directly to invoking it via hidden PowerShell Start-Process, preventing Task Scheduler from creating a visible console window. Documentation is extended to explain the wrapper behavior and process-tree effect.

Changes

Windows autostart hidden-console wrapper

Layer / File(s) Summary
Windows autostart hidden-console wrapper implementation and documentation
libs/cua-driver-rs/crates/cua-driver/src/autostart.rs
Extended inline documentation for the REGISTER_PS PowerShell script to describe the hidden-console launch approach and its effects on window visibility. Updated the scheduled task's $action definition to run powershell.exe with Start-Process -WindowStyle Hidden to launch cua-driver.exe serve, replacing direct executable invocation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • trycua/cua#1550: Both PRs modify libs/cua-driver-rs/crates/cua-driver/src/autostart.rs's Windows REGISTER_PS PowerShell script used by the cua-driver autostart enable scheduled-task registration.
  • trycua/cua#1630: Both PRs modify the Windows autostart.rs inline PowerShell scheduled-task registration (REGISTER_PS) used by cua-driver autostart enable with adjustments to task execution and elevation handling.
  • trycua/cua#1632: Both PRs modify libs/cua-driver-rs/crates/cua-driver/src/autostart.rs's Windows autostart behavior by adjusting how PowerShell Start-Process is used around task execution and registration.

Poem

🐰 A console ghost haunted the logon,
Appearing with daemon's dawn;
PowerShell wraps it, hidden from sight,
Task Scheduler's window takes flight!
No more eyesore—smooth startup delight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: replacing direct executable launch with a PowerShell wrapper to hide the console window at logon.
Linked Issues check ✅ Passed The PR implements Option 2 from issue #1645, changing the task action to use a hidden PowerShell Start-Process wrapper, with updated documentation in autostart.rs.
Out of Scope Changes check ✅ Passed All changes are scoped to autostart.rs script and documentation, directly addressing the console window visibility issue without introducing unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libs/cua-driver-rs/crates/cua-driver/src/autostart.rs`:
- Around line 165-168: The PowerShell snippet used to create the scheduled task
wraps $env:CUA_DRIVER_AS_EXE and $env:USERPROFILE in single quotes so they are
not expanded; change the nested Start-Process invocation in the string (the line
building the New-ScheduledTaskAction command) to use double quotes around the
environment variables (e.g. -FilePath "$env:CUA_DRIVER_AS_EXE" and
-WorkingDirectory "$env:USERPROFILE") so PowerShell expands them at runtime, and
update the Rust string escaping accordingly so the inner double quotes are
properly escaped in the autostart code that constructs the scheduled-task
action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8230c17-28b9-4ba5-ae4b-65f545f3fb4d

📥 Commits

Reviewing files that changed from the base of the PR and between b4c0593 and f59bece.

📒 Files selected for processing (1)
  • libs/cua-driver-rs/crates/cua-driver/src/autostart.rs

Comment on lines +165 to +168
$action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument "-NoProfile -WindowStyle Hidden -NonInteractive -Command `"Start-Process -FilePath '$env:CUA_DRIVER_AS_EXE' -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory '$env:USERPROFILE'`"" `
-WorkingDirectory $env:USERPROFILE

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.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In PowerShell, are environment variables like $env:CUA_DRIVER_AS_EXE and $env:USERPROFILE expanded inside single-quoted strings, or only in double-quoted/unquoted arguments?

💡 Result:

In PowerShell, environment variables like $env:CUA_DRIVER_AS_EXE and $env:USERPROFILE are not expanded inside single-quoted strings [1][2]. Single-quoted strings in PowerShell are treated as verbatim strings, meaning no variable substitution or expression evaluation occurs; the content is passed exactly as written [1][2][3]. Conversely, environment variables are expanded inside double-quoted strings because these are defined as expandable strings [1][2]. Additionally, when passing arguments to commands in PowerShell, unquoted arguments are also subject to expansion and interpretation [1]. If you need to include the value of an environment variable within a single-quoted context, you must use other methods such as string concatenation (e.g., '$' + $env:USERPROFILE + '$') or the format operator (e.g., "'{0}'" -f $env:USERPROFILE) [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="libs/cua-driver-rs/crates/cua-driver/src/autostart.rs"
nl -ba "$FILE" | sed -n '140,190p'

Repository: trycua/cua

Length of output: 97


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="libs/cua-driver-rs/crates/cua-driver/src/autostart.rs"

# Print with line numbers (cat -n should exist)
cat -n "$FILE" | sed -n '150,190p'

Repository: trycua/cua

Length of output: 3108


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "Start-Process -FilePath" libs/cua-driver-rs/crates/cua-driver/src/autostart.rs libs/cua-driver-rs/crates/cua-driver/src -S

Repository: trycua/cua

Length of output: 1020


Fix PowerShell scheduled-task quoting so $env:* expands in autostart.

In libs/cua-driver-rs/crates/cua-driver/src/autostart.rs line 167, $env:CUA_DRIVER_AS_EXE and $env:USERPROFILE are wrapped in single quotes inside the nested Start-Process -Command, so PowerShell won’t expand them; the task will pass literal $env:* text instead of real paths.

🐛 Proposed fix
 $action = New-ScheduledTaskAction `
     -Execute 'powershell.exe' `
-    -Argument "-NoProfile -WindowStyle Hidden -NonInteractive -Command `"Start-Process -FilePath '$env:CUA_DRIVER_AS_EXE' -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory '$env:USERPROFILE'`"" `
+    -Argument "-NoProfile -WindowStyle Hidden -NonInteractive -Command `"Start-Process -FilePath `"$env:CUA_DRIVER_AS_EXE`" -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory `"$env:USERPROFILE`"`"" `
     -WorkingDirectory $env:USERPROFILE
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument "-NoProfile -WindowStyle Hidden -NonInteractive -Command `"Start-Process -FilePath '$env:CUA_DRIVER_AS_EXE' -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory '$env:USERPROFILE'`"" `
-WorkingDirectory $env:USERPROFILE
$action = New-ScheduledTaskAction `
-Execute 'powershell.exe' `
-Argument "-NoProfile -WindowStyle Hidden -NonInteractive -Command `"Start-Process -FilePath `"$env:CUA_DRIVER_AS_EXE`" -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory `"$env:USERPROFILE`"`"" `
-WorkingDirectory $env:USERPROFILE
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/cua-driver-rs/crates/cua-driver/src/autostart.rs` around lines 165 -
168, The PowerShell snippet used to create the scheduled task wraps
$env:CUA_DRIVER_AS_EXE and $env:USERPROFILE in single quotes so they are not
expanded; change the nested Start-Process invocation in the string (the line
building the New-ScheduledTaskAction command) to use double quotes around the
environment variables (e.g. -FilePath "$env:CUA_DRIVER_AS_EXE" and
-WorkingDirectory "$env:USERPROFILE") so PowerShell expands them at runtime, and
update the Rust string escaping accordingly so the inner double quotes are
properly escaped in the autostart code that constructs the scheduled-task
action.

@f-trycua

Copy link
Copy Markdown
Collaborator

Tested empirically — CodeRabbit's quoting concern is a false positive in this case. The '$env:CUA_DRIVER_AS_EXE' is inside an outer double-quoted PowerShell string (the -Argument value), so $env:CUA_DRIVER_AS_EXE expands first; the single quotes survive as literal chars around the expanded value, which is exactly what Start-Process -FilePath needs.

Verified on a clean Windows 11 24H2 VM. After cua-driver autostart enable, Get-ScheduledTask cua-driver-serve | Select Actions shows:

Arguments: -NoProfile -WindowStyle Hidden -NonInteractive -Command "Start-Process -FilePath 'C:\\Users\\<user>\\.cua-driver\\packages\\releases\\...\\cua-driver.exe' -ArgumentList 'serve' -WindowStyle Hidden -WorkingDirectory 'C:\\Users\\<user>'"

Paths expanded correctly.

schtasks /Run /TN cua-driver-serve then spawns the daemon. Win32 EnumWindows + IsWindowVisible enumeration of the daemon's pid: 0 visible windows. MainWindowHandle = 0. Fix works as designed.

Merging — thanks for the patch @hippoley!

@f-trycua
f-trycua merged commit f8e56d6 into trycua:main May 22, 2026
1 of 2 checks passed
f-trycua added a commit that referenced this pull request May 24, 2026
…ry install when it already exists (#1685)

Symptom: user upgrades cua-driver (e.g. via install-local.ps1 to pick
up the hidden-console wrapper from #1654), then runs
`cua-driver autostart kick`, then sees a visible console window
again. Repro confirmed: the scheduled task's <Command> path stayed
hard-pointed at the previous release-install dir (a binary lacking
the wrapper code), so kick spawned the OLD binary.

Both install.ps1 and install-local.ps1 only re-registered the task
when -AutoStart was passed. Users on the upgrade path don't pass it
(they're not opting INTO autostart - they already have it).

Fix: both scripts now sniff for an existing `cua-driver-serve` task
post-install and re-register it pointing at the freshly-installed
binary, even without -AutoStart. The re-register is idempotent and
covers the upgrade case explicitly. If no task is registered, nothing
changes (still need -AutoStart to opt in initially).

End-to-end: user runs install-local.ps1, the just-built binary's
REGISTER_PS produces the wrapped task action, kick now spawns
hidden.

Replaced em-dashes in added comments with ASCII hyphens - the file
gets rewritten as UTF-8 on edit, but PS 5.1's parser had read older
em-dashes in the same file as windows-1252 successfully (mixed-
encoding), and treating new bytes as UTF-8 surfaced unterminated-
string errors. Stay on ASCII in newly-added blocks to avoid drift.
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.

cua-driver-rs (Windows): autostart task's daemon spawns a visible console window at logon

2 participants