提交前查重 / Duplicate check
本仓库此前无 Windows 控制台窗口相关的报告。相关(但主题不同):#5(Windows CLI discovery)。
涉及区域 / Affected area
Issue 类型 / Issue type
Bug 报告 / Bug report
摘要 / Summary
在 Windows 上,resolveGitBranch() 调用 execFileSync('git', …) 时未传 windowsHide: true。当 DSH 宿主是无控制台的 GUI 进程(DSH Desktop / Electron)时,Windows 会为每次调用新建一个可见的控制台窗口,表现为一个 Windows Terminal 窗口闪现后立刻消失。由于该函数位于会话投影(session projection)路径上,因此每次切换/加载对话都会闪一次窗口。
预期结果 / Expected outcome
- 切换对话、加载会话或执行 git 分支探测时,不出现任何终端/控制台窗口。
resolveGitBranch() 的行为(返回值、超时、失败时回退到未过滤视图)完全不变。
- 在非 Windows 平台上行为不变(
windowsHide 在 POSIX 上是 no-op)。
详情或复现步骤 / Details or reproduction steps
受影响文件: plugins/dsh-mnemon-source-runtime/src/git-branch.ts
const output = execFileSync('git', ['-C', root, 'branch', '--show-current'], {
encoding: 'utf8',
timeout: GIT_BRANCH_TIMEOUT_MS,
stdio: ['ignore', 'pipe', 'ignore'],
// ← 缺少 windowsHide: true
})
调用点(会话投影,src/index.ts):
const projection = (workspaceId) => controller.contextProjection(resolveGitBranch(workspaceId))
复现步骤:
- 在 DSH Desktop(Windows 11,默认终端宿主为 Windows Terminal)上安装
dsh-mnemon。
- 在同一个 git 仓库工作区中至少打开两个对话。
- 在侧边栏中来回点击切换对话。
- 实际结果: 每次切换都有一个终端窗口闪现并立即关闭。
- 预期结果: 无窗口;git 探测应对用户完全不可见。
根因说明:
当父进程没有控制台、且未传 CREATE_NO_WINDOW 时,CreateProcess 会为控制台子系统的子进程新建一个可见控制台。windowsHide: true 正是让 Node 传递 CREATE_NO_WINDOW 的开关。本项目其余 spawn 调用(如 dsh-mnemon/lib/index.js:6072、dsh-mnemon-source-memory-spaces/lib/process-BvrgxPNP.js:18)均已正确设置该标志,仅此处遗漏。
环境信息 / Environment
- DSH 版本 / DSH version: DSH Desktop 2.0.10
- dsh-mnemon 版本或 commit / dsh-mnemon version or commit: 0.5.10
- dsh-mnemon-source-runtime 版本 / version: 0.5.7
- Mnemon 版本 / Mnemon version: @mnemon-dev/mnemon 0.2.8
- Node.js / pnpm: DSH Desktop 内置 Node(Electron)
- 操作系统或浏览器 / OS or browser: Windows 11 教育版 10.0.26200(Windows Terminal 1.24.11911.0,Win11 默认终端宿主)
- Provider 或相关配置(已脱敏)/ Provider or related configuration (redacted): N/A(与本问题无关)
- git 版本: 2.53.0.windows.1(
D:\Git\cmd\git.exe)
Bug 证据 / Bug evidence
对照实验(A/B),从无控制台的父进程(pythonw.exe)spawn git --version,同时用 EnumWindows 枚举窗口:
不加 windowsHide(当前代码):
NEW terminal windows: 2
class=CASCADIA_HOSTING_WINDOW_CLASS visible=True pid=2772 title='D:\\Git\\cmd\\git.exe'
class=PseudoConsoleWindow visible=True pid=19800 title=''
加上 windowsHide: true:
NEW terminal windows: 0
(no window: child ran without a visible console)
同路径的进程创建链(可见窗口正是由这条链产生):
git.exe
→ conhost.exe 0x4
→ OpenConsole.exe -Embedding
→ WindowsTerminal.exe -Embedding ← 用户看到的闪现窗口
前台窗口轮询(每 80 ms 取一次 GetForegroundWindow)直接抓到了闪现:
FOCUS -> WindowsTerminal [...|CASCADIA_HOSTING_WINDOW_CLASS|...\mnemon-win32-x64\bin\mnemon.exe]
冒烟测试 / Smoke test
- 测试环境 / Test environment: Windows 11 10.0.26200,DSH Desktop 2.0.10,Windows Terminal 为默认终端宿主
- 执行命令或操作 / Commands or actions: 在已安装的
lib/index.js 打上补丁后,重新导入模块并连续执行会话投影路径 4 次
- 实际结果 / Observed result: 新增终端窗口数 = 0(打补丁前每次运行 1 个)
- 对照版本或配置 / Control version or configuration: 未打补丁的
execFileSync,同一环境下每次运行均产生 1 个可见窗口
引用代码 / Code references
plugins/dsh-mnemon-source-runtime/src/git-branch.ts(resolveGitBranch)
plugins/dsh-mnemon-source-runtime/src/index.ts(projection 调用点)
补丁草案 / Patch proposal
--- a/plugins/dsh-mnemon-source-runtime/src/git-branch.ts
+++ b/plugins/dsh-mnemon-source-runtime/src/git-branch.ts
@@
const output = execFileSync('git', ['-C', root, 'branch', '--show-current'], {
encoding: 'utf8',
timeout: GIT_BRANCH_TIMEOUT_MS,
+ windowsHide: true,
stdio: ['ignore', 'pipe', 'ignore'],
})
windowsHide 在 POSIX 上是文档化的 no-op,因此可无条件添加。
补充信息 / Additional context
@mnemon-dev/mnemon 的 npm CLI 包装器(lib/child.js)存在同类问题,因属于另一上游仓库,已单独报告至 mnemon-dev/mnemon#143。
- 这是 Windows 上观感明显但非致命的缺陷:它在每次切换对话时触发,正常使用中极易察觉。
- 建议顺带考虑加一条 CI/lint 守卫:断言 Windows 上每个
spawn/execFile/spawnSync 调用点都传入 windowsHide,以防此类回归。
提交前查重 / Duplicate check
本仓库此前无 Windows 控制台窗口相关的报告。相关(但主题不同):#5(Windows CLI discovery)。
涉及区域 / Affected area
Issue 类型 / Issue type
Bug 报告 / Bug report
摘要 / Summary
在 Windows 上,
resolveGitBranch()调用execFileSync('git', …)时未传windowsHide: true。当 DSH 宿主是无控制台的 GUI 进程(DSH Desktop / Electron)时,Windows 会为每次调用新建一个可见的控制台窗口,表现为一个 Windows Terminal 窗口闪现后立刻消失。由于该函数位于会话投影(session projection)路径上,因此每次切换/加载对话都会闪一次窗口。预期结果 / Expected outcome
resolveGitBranch()的行为(返回值、超时、失败时回退到未过滤视图)完全不变。windowsHide在 POSIX 上是 no-op)。详情或复现步骤 / Details or reproduction steps
受影响文件:
plugins/dsh-mnemon-source-runtime/src/git-branch.ts调用点(会话投影,
src/index.ts):复现步骤:
dsh-mnemon。根因说明:
当父进程没有控制台、且未传
CREATE_NO_WINDOW时,CreateProcess会为控制台子系统的子进程新建一个可见控制台。windowsHide: true正是让 Node 传递CREATE_NO_WINDOW的开关。本项目其余 spawn 调用(如dsh-mnemon/lib/index.js:6072、dsh-mnemon-source-memory-spaces/lib/process-BvrgxPNP.js:18)均已正确设置该标志,仅此处遗漏。环境信息 / Environment
D:\Git\cmd\git.exe)Bug 证据 / Bug evidence
对照实验(A/B),从无控制台的父进程(
pythonw.exe)spawngit --version,同时用EnumWindows枚举窗口:不加
windowsHide(当前代码):加上
windowsHide: true:同路径的进程创建链(可见窗口正是由这条链产生):
前台窗口轮询(每 80 ms 取一次
GetForegroundWindow)直接抓到了闪现:冒烟测试 / Smoke test
lib/index.js打上补丁后,重新导入模块并连续执行会话投影路径 4 次execFileSync,同一环境下每次运行均产生 1 个可见窗口引用代码 / Code references
plugins/dsh-mnemon-source-runtime/src/git-branch.ts(resolveGitBranch)plugins/dsh-mnemon-source-runtime/src/index.ts(projection调用点)补丁草案 / Patch proposal
windowsHide在 POSIX 上是文档化的 no-op,因此可无条件添加。补充信息 / Additional context
@mnemon-dev/mnemon的 npm CLI 包装器(lib/child.js)存在同类问题,因属于另一上游仓库,已单独报告至mnemon-dev/mnemon#143。spawn/execFile/spawnSync调用点都传入windowsHide,以防此类回归。