SIGN IN SIGN UP
denoland / deno UNCLAIMED

A modern runtime for JavaScript and TypeScript.

0 0 16 Rust

fix(ext/node): honor windowsHide in child_process spawn (#34627)

## Summary

Fixes denoland/deno#31368 — `npm:clipboardy`'s `clipboard.read()` was
changing the Windows console title to "Windows PowerShell" and never
restoring it, while the same code worked fine on Node.

clipboardy spawns PowerShell with `windowsHide: true` to read the
clipboard. Node honors that option by setting `CREATE_NO_WINDOW` on
`CreateProcessW`, so the child runs without inheriting the parent's
console. Deno's polyfill validated and normalized `windowsHide`, but
then silently dropped it — the option never reached the spawn op, so
PowerShell inherited Deno's console and renamed its title bar.

The underlying spawn logic already applies `CREATE_NO_WINDOW` when
`uv_process_flags::WindowsHide` is set (see
`runtime/subprocess_windows/src/process.rs`); no caller was setting the
bit.

## Changes

- `runtime/subprocess_windows::Command` gains a `windows_hide` field, a
`windows_hide(bool)` setter, and ORs `uv_process_flags::WindowsHide`
into the spawn flags.
- `SpawnArgs` (Windows-only) gains a `windows_hide` field that is
applied to the command in `create_command`.
- `nodeSpawnChild` / `nodeSpawnSyncChild` (and their op call sites in
`ext/process/40_process.js`) forward `windowsHide` to the ops.
- `ChildProcess#spawnInternal` and `spawnSync` read `windowsHide` from
the options (defaulting to `true` to match Node's documented default)
and pass it through.
- `normalizeSpawnArguments` and `execFile` normalize the option to
`true` unless the caller explicitly passes `false`, matching Node
behavior.

## Test plan

- [ ] Windows: run the repro from the issue (`npm:clipboardy` +
`clipboard.read()`) and confirm the console title is unchanged after the
call.
- [ ] Windows: existing `tests/unit_node/child_process_test.ts` and the
`tests/specs/node/child_process_*` spec suites continue to pass.
- [ ] Linux / macOS: builds and tests are unaffected — the new
`windows_hide` field on `SpawnArgs` is `#[cfg(windows)]`-gated, and the
camelCase JS field is silently ignored by serde on non-Windows.

Closes denoland/divybot#374

Co-authored-by: divybot <divybot@users.noreply.github.com>
Co-authored-by: Divy Srivastava <me@littledivy.com>
E
em committed
d11c5d08e2e52fa6d7ebdda6621c1d638053d63d
Parent: d094bc8
Committed by GitHub <noreply@github.com> on 5/31/2026, 4:05:00 PM