Skip to content

remote_server: Use CreateProcess to spawn daemon on Windows - #55292

Merged
reflectronic merged 2 commits into
zed-industries:mainfrom
sergio-u:fix/spawn-server-windows-no-shell
Oct 14, 2026
Merged

reflectronic merged 2 commits into
zed-industries:mainfrom
sergio-u:fix/spawn-server-windows-no-shell

Conversation

@sergio-u

Copy link
Copy Markdown
Contributor

When connecting to a Windows host over SSH, the proxy fails to start the daemon and the user sees "failed to spawn server."

Root cause

spawn_server_windows invokes the daemon via shell_execute_from_explorer, which goes through COM ShellWindows / IShellDispatch2::ShellExecute. That path requires both:

  • explorer.exe running in the caller's session, and
  • an interactive desktop / window station.

Neither is available when zed-remote-server proxy is launched by sshd: sshd-spawned processes live in a non-interactive window station with no Explorer. The COM call fails, the run daemon never starts, the proxy's 10s socket-existence poll times out, and the connection fails.

A commenter on #48966 reports the connection succeeds after first logging in via RDP, which is consistent with this diagnosis: RDP login populates the session with explorer.exe and an interactive window station.

Fix

Replace the COM path with a direct Command::spawn, matching the non-Windows branch. Use DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP creation flags so the daemon has no inherited console and is not killed by Ctrl+C/Break broadcast to the parent's group when the proxy exits.

Bypass util::new_command because it presets CREATE_NO_WINDOW, which Win32 disallows combining with DETACHED_PROCESS. Drop one layer to smol::process::Command directly to keep the disallowed-methods lint happy.

Also drop the now-unused shell_execute_from_explorer module and the windows crate dependency it pulled in.

No automated test is included: exercising this path requires a headless OpenSSH-Server-on-Windows host with a non-interactive window station, which CI doesn't currently provide. Verified manually that macOS client -> Windows host over SSH establishes the connection successfully where it previously timed out.

Closes #48966

Self-Review Checklist:

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content is consistent with the UI/UX checklist
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Release Notes:

  • Fixed remote server failing to start when connecting to a Windows host over SSH

@cla-bot

cla-bot Bot commented Apr 30, 2026

Copy link
Copy Markdown

We require contributors to sign our Contributor License Agreement, and we don't have @sergio-u on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@zed-community-bot zed-community-bot Bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label Apr 30, 2026
@sergio-u

Copy link
Copy Markdown
Contributor Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Apr 30, 2026
@cla-bot

cla-bot Bot commented Apr 30, 2026

Copy link
Copy Markdown

The cla-bot has been summoned, and re-checked this pull request!

@sergio-u
sergio-u force-pushed the fix/spawn-server-windows-no-shell branch from d8a2df0 to be7983b Compare May 11, 2026 14:13
@smitbarmase smitbarmase added the platform:remote Remote development, SSH and zed-remote-server label May 29, 2026
@sergio-u
sergio-u force-pushed the fix/spawn-server-windows-no-shell branch from be7983b to 8ab94eb Compare June 2, 2026 21:21
@sergio-u
sergio-u force-pushed the fix/spawn-server-windows-no-shell branch 2 times, most recently from 4a5a33d to 6c69327 Compare June 26, 2026 17:52
@kevinsanchh

Copy link
Copy Markdown

Just confirming this fix is still needed and very much wanted. On the current stable (Zed v1.15.0, macOS client → Windows host), the old COM/shell_execute_from_explorer spawn path still fails over a fresh SSH session: failed to spawn server, no socket/log files in $LOCALAPPDATA/Zed/. The only workaround remains establishing an interactive logon (RDP) session first — exactly the problem this PR addresses.

This blocks macOS/Linux → Windows remote development entirely until merged. Any chance of getting this reviewed and in? Happy to test a preview build with this change. 👍

@iakovmarkov

Copy link
Copy Markdown

I'm running into this bug on my new development setup as well. Establishing an RDP session first works around it, but it's not exactly ideal...

I'd love to see this PR merged. @reflectronic, is there anything I can do to help move it forward?

I checked the merge conflicts locally, and it looks like Cargo.lock is the only conflicting file. Happy to help resolve that or test the changes on fresh Windows 11 box.

sergio-u and others added 2 commits October 14, 2026 03:51
When connecting to a Windows host over SSH, the proxy fails to start
the daemon and the user sees "failed to spawn server."

**Root cause**

`spawn_server_windows` invokes the daemon via
`shell_execute_from_explorer`, which goes through COM `ShellWindows` /
`IShellDispatch2::ShellExecute`. That path requires both:

- `explorer.exe` running in the caller's session, and
- an interactive desktop / window station.

Neither is available when `zed-remote-server proxy` is launched by
sshd: sshd-spawned processes live in a non-interactive window station
with no Explorer. The COM call fails, the `run` daemon never starts,
the proxy's 10s socket-existence poll times out, and the connection
fails.

**Fix**

Replace the COM path with a direct `Command::spawn`, matching the
non-Windows branch. Use `DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP`
creation flags so the daemon has no inherited console and is not
killed by Ctrl+C/Break broadcast to the parent's group when the proxy
exits.

Bypass `util::new_command` because it presets `CREATE_NO_WINDOW`, which
Win32 disallows combining with `DETACHED_PROCESS`. Drop one layer to
`smol::process::Command` directly to keep the disallowed-methods lint
happy.

Also drop the now-unused `shell_execute_from_explorer` module and the
`windows` crate dependency it pulled in.

Release Notes:

- Fixed remote server failing to start when connecting to a Windows host over SSH

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@reflectronic
reflectronic force-pushed the fix/spawn-server-windows-no-shell branch from 6c69327 to 6320baf Compare October 14, 2026 08:44

@reflectronic reflectronic left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@reflectronic
reflectronic added this pull request to the merge queue Oct 14, 2026
Merged via the queue into zed-industries:main with commit 7dc397b Oct 14, 2026
36 checks passed
@iakovmarkov

Copy link
Copy Markdown

Hell yes, super stoked to see this merged. I'm running a patched build of Zed server on my Windows boxes and it works really well.

Thanks everyone for your work on Zed!

@sergio-u

Copy link
Copy Markdown
Contributor Author

Awesome! Thank you for getting this merged

amirkhakshour pushed a commit to SourceShift/zed-mini-ork that referenced this pull request Oct 18, 2026
…stries#55292)

When connecting to a Windows host over SSH, the proxy fails to start the
daemon and the user sees "failed to spawn server."

**Root cause**

`spawn_server_windows` invokes the daemon via
`shell_execute_from_explorer`, which goes through COM `ShellWindows` /
`IShellDispatch2::ShellExecute`. That path requires both:

- `explorer.exe` running in the caller's session, and
- an interactive desktop / window station.

Neither is available when `zed-remote-server proxy` is launched by sshd:
sshd-spawned processes live in a non-interactive window station with no
Explorer. The COM call fails, the `run` daemon never starts, the proxy's
10s socket-existence poll times out, and the connection fails.

A commenter on zed-industries#48966 reports the connection succeeds after first
logging in via RDP, which is consistent with this diagnosis: RDP login
populates the session with `explorer.exe` and an interactive window
station.

**Fix**

Replace the COM path with a direct `Command::spawn`, matching the
non-Windows branch. Use `DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP`
creation flags so the daemon has no inherited console and is not killed
by Ctrl+C/Break broadcast to the parent's group when the proxy exits.

Bypass `util::new_command` because it presets `CREATE_NO_WINDOW`, which
Win32 disallows combining with `DETACHED_PROCESS`. Drop one layer to
`smol::process::Command` directly to keep the disallowed-methods lint
happy.

Also drop the now-unused `shell_execute_from_explorer` module and the
`windows` crate dependency it pulled in.

No automated test is included: exercising this path requires a headless
OpenSSH-Server-on-Windows host with a non-interactive window station,
which CI doesn't currently provide. Verified manually that macOS client
-> Windows host over SSH establishes the connection successfully where
it previously timed out.

Closes zed-industries#48966

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed remote server failing to start when connecting to a Windows host
over SSH

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: John Tur <john-tur@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions platform:remote Remote development, SSH and zed-remote-server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS → Windows SSH remote fails: socket/log files not created in "$LOCALAPPDATA/Zed/"

5 participants