Repository navigation
Replies: 1 comment
|
本仓的代码断言逐条属实,我全核实了。但你漏掉了一个上游反证 —— 1. ✅ 你的定位在代码层面成立
function spawnBrowserLauncher(url: string): ChildProcess {
return spawn(process.execPath, [
'--input-type=module',
'--eval', BROWSER_OPENER_PROGRAM,
'--', url,
], {
env: scrubbedParentEnv(),
stdio: ['ignore', 'inherit', 'pipe'],
})
}确实没有 「open 在 Windows 起 PowerShell」本仓自证: 依赖: console-wide CTRL_C 的注释也确实存在 —— if (this.platform === 'win32') {
if (signal === 'SIGINT') {
// Windows has no process-group signalling: a `\x03` input write is the
// Ctrl-C delivery path the console host turns into a console-wide
// CTRL_C event for attached processes. …
this.terminal.write('\x03')
2.
|
Uh oh!
There was an error while loading. Please reload this page.
环境
Windows 11 24H2
dsh --profile web(默认 openBrowser: true;端口无关,3080/3081 均可复现)
默认浏览器 Chrome(任何经该链冷启动的默认浏览器同理)
现象
Chrome 当时并未运行,由 dsh web 启动时自动拉起;会话期间又打开了若干标签页。在运行 dsh web 的终端按 Ctrl+C 退出后,Chrome 全部窗口与标签页被一并关闭。
复现步骤
确保 Chrome 完全退出(任务管理器确认无残留 chrome.exe);
在 Windows 终端运行 dsh --profile web(不带 --no-open),等它自动打开浏览器;
在自动打开的 Chrome 中再开几个标签页;
回到终端按 Ctrl+C;
Chrome 整个浏览器随宿主一起退出,标签页全部丢失。
关键判定(解释偶发性):若 dsh 启动前 Chrome 已在正常运行(由 GUI 正常启动、无控制台),dsh web 只是在既有主进程里开一个新标签,Ctrl+C 不影响它——只有"浏览器由 dsh 启动链冷启动"这一形态中招。
根因(代码定位)
packages/bundle/web-app/src/index.ts 的 spawnBrowserLauncher 以 stdio: ['ignore', 'inherit', 'pipe'] 且不带 detached spawn node helper——helper 与 dsh web 宿主共享同一控制台;
npm open@11 的 Windows 实现 spawn powershell.exe(执行 Start ),PowerShell 作为控制台子系统子进程附着同一控制台;
由该链冷启动的 Chrome 主进程附着该控制台(与"从 cmd 运行 chrome --enable-logging 能在控制台看到日志"是同一机制);
终端 Ctrl+C → conhost 把 CTRL_C_EVENT 广播给该控制台附着的所有进程 → Chrome 收到控制台事件后退出整个浏览器会话。
佐证:本仓库自身在 packages/subprocess/subprocess-local/src/terminal.ts(signalForeground 的 win32 分支)注释里已写明"Windows 无进程组信号:conhost 把 \x03 变成对全部附着进程的 console-wide CTRL_C event";#3195 的对照实验同样证明共享控制台是 ctrl 事件波及面的决定因素(独立控制台拉起的实例存活)。
同族讨论(方向不同):#3195 / #7957 是宿主被杂散 ctrl 事件误杀;#8734 是同一条"dsh 冷启动整个浏览器"链的另一种后果。本报告的症状(用户浏览器被 Ctrl+C 连带关闭)未见既有 issue。
建议修复(已在本地验证)
spawnBrowserLauncher 在 win32 上 detached: true(libuv 映射 DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP):
helper 自此没有控制台;它 spawn 的 PowerShell、以及 PowerShell 经 ShellExecute 拉起的浏览器均不再附着宿主控制台,后续任何 console-wide ctrl 事件都到不了它们;
helper stdout 由 inherit 改为 pipe 并由宿主转发,浏览器交接的可观测性与测试证据通道保持不变;stderr 诊断路径不变;
新增 tests/browser-open-spawn.spec.ts 钉住标志(win32 detached + pipe 转发;POSIX 保持非 detach);
README.md / README.zh.md 双语补充行为说明。
回归:vitest 4 个用例通过(browser-open.spec.ts 1 + browser-open-spawn.spec.ts 3);oxlint 0 警告;whitespace / vendor manifest 钩子通过。
验收条件
按复现步骤操作,Ctrl+C 退出 dsh web 后,Chrome 及其全部标签页存活;
Chrome 预先运行的既有形态行为不变(新标签照开、退出互不影响);
浏览器打不开时的 stderr 诊断与 "use the dsh web URL printed at startup" 兜底不变;
POSIX 平台行为不变。
All reactions