fix windows desktop terminal popups (#1199)

This commit is contained in:
ekko
2026-06-01 12:20:10 +08:00
committed by GitHub
parent aa7c1c4fbb
commit 022e18dc8f
5 changed files with 87 additions and 20 deletions
@@ -10,6 +10,7 @@ delimited JSON request/response protocol over a local socket.
from __future__ import annotations
import argparse
import asyncio
import atexit
import copy
import errno
@@ -71,6 +72,14 @@ def _hidden_subprocess_kwargs() -> dict[str, int]:
return {"creationflags": getattr(subprocess, "CREATE_NO_WINDOW", 0)}
def _add_hidden_creationflags(kwargs: dict[str, Any], create_no_window: int) -> None:
flags = kwargs.get("creationflags", 0) or 0
try:
kwargs["creationflags"] = int(flags) | create_no_window
except Exception:
kwargs["creationflags"] = create_no_window
def _install_windows_hidden_subprocess_defaults() -> None:
"""Hide console windows for subprocesses launched inside desktop bridge runs.
@@ -87,18 +96,26 @@ def _install_windows_hidden_subprocess_defaults() -> None:
return
original_popen = subprocess.Popen
original_create_subprocess_exec = asyncio.create_subprocess_exec
original_create_subprocess_shell = asyncio.create_subprocess_shell
create_no_window = getattr(subprocess, "CREATE_NO_WINDOW", 0) or 0x08000000
class HiddenPopen(original_popen): # type: ignore[misc, valid-type]
def __init__(self, *args: Any, **kwargs: Any) -> None:
flags = kwargs.get("creationflags", 0) or 0
try:
kwargs["creationflags"] = int(flags) | create_no_window
except Exception:
kwargs["creationflags"] = create_no_window
_add_hidden_creationflags(kwargs, create_no_window)
super().__init__(*args, **kwargs)
async def hidden_create_subprocess_exec(*args: Any, **kwargs: Any) -> Any:
_add_hidden_creationflags(kwargs, create_no_window)
return await original_create_subprocess_exec(*args, **kwargs)
async def hidden_create_subprocess_shell(*args: Any, **kwargs: Any) -> Any:
_add_hidden_creationflags(kwargs, create_no_window)
return await original_create_subprocess_shell(*args, **kwargs)
subprocess.Popen = HiddenPopen # type: ignore[assignment]
asyncio.create_subprocess_exec = hidden_create_subprocess_exec # type: ignore[assignment]
asyncio.create_subprocess_shell = hidden_create_subprocess_shell # type: ignore[assignment]
subprocess._hermes_hidden_defaults_installed = True # type: ignore[attr-defined]
@@ -22,12 +22,15 @@ function bundledCliPythonForWindows(hermesBin: string): string | null {
if (envPython) return envPython
if (basename(hermesBin).toLowerCase() !== 'hermes.exe') return null
const pythonw = resolve(dirname(hermesBin), '..', 'pythonw.exe')
if (existsSync(pythonw)) return pythonw
const python = resolve(dirname(hermesBin), '..', 'python.exe')
return existsSync(python) ? python : null
}
function withWindowsHide<T extends ExecFileOptions | SpawnOptions>(options?: T): T {
if (process.platform !== 'win32') return (options || {}) as T
return { windowsHide: true, ...(options || {}) } as T
}
export function resolveHermesInvocation(hermesBin = resolveHermesBin()): HermesInvocation {
if (process.platform === 'win32') {
const python = bundledCliPythonForWindows(hermesBin)
@@ -47,7 +50,7 @@ export function execHermesWithBin(
execFile(
invocation.command,
[...invocation.argsPrefix, ...args],
{ ...options, encoding: 'utf8' },
{ ...withWindowsHide(options), encoding: 'utf8' },
(error, stdout, stderr) => {
if (error) {
rejectExec(Object.assign(error, { stdout, stderr }))
@@ -69,7 +72,7 @@ export function spawnHermesWithBin(
options?: SpawnOptions,
): ChildProcess {
const invocation = resolveHermesInvocation(hermesBin)
return spawn(invocation.command, [...invocation.argsPrefix, ...args], options || {})
return spawn(invocation.command, [...invocation.argsPrefix, ...args], withWindowsHide(options))
}
export function spawnHermes(args: readonly string[], options?: SpawnOptions): ChildProcess {