From a9483f0bf7528ba28ae383219e35acb4f817c8e0 Mon Sep 17 00:00:00 2001 From: Aikiooo <78739437+Aikiooo@users.noreply.github.com> Date: Thu, 10 Sep 2026 18:24:07 +0200 Subject: [PATCH] fix(win): hide the console window forked by the console-list agent WindowsPtyAgent.kill() calls _getConsoleProcessList(), which forks conpty_console_list_agent. fork() inherits stdio, so on Windows that child is given a console of its own, and a console window appears every time a pty is killed. In an embedding application it can also take focus from the host's window. windowsHide still leaves the helper a console - it needs one, because getConsoleProcessList() calls FreeConsole() then AttachConsole(shellPid) - it just gives it no window. @types/node's ForkOptions does not declare windowsHide (still true on DefinitelyTyped master), so the options object is typed to keep strict building. --- src/windowsPtyAgent.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/windowsPtyAgent.ts b/src/windowsPtyAgent.ts index 73f83d6ec..0d61bf2f1 100644 --- a/src/windowsPtyAgent.ts +++ b/src/windowsPtyAgent.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { fork } from 'child_process'; +import { fork, ForkOptions } from 'child_process'; import { Socket } from 'net'; import { ArgvOrCommandLine } from './types'; import { ConoutConnection, IConoutConnection } from './windowsConoutConnection'; @@ -228,7 +228,11 @@ export class WindowsPtyAgent { return Promise.resolve([]); } return new Promise(resolve => { - const agent = fork(path.join(__dirname, 'conpty_console_list_agent'), [ this._innerPid.toString() ]); + // The helper needs a console (AttachConsole) but no window: without + // windowsHide, killing a pty flashes a console window on screen. + // Cast: @types/node's ForkOptions omits windowsHide. + const forkOptions = { windowsHide: true } as ForkOptions; + const agent = fork(path.join(__dirname, 'conpty_console_list_agent'), [ this._innerPid.toString() ], forkOptions); agent.on('message', message => { clearTimeout(timeout); resolve(message.consoleProcessList);