zai-org / zai-org/feedback

[Bug] Windows: 外部进程探测 `ZCode.exe --version` 会触发主窗口 show()/focus() 抢前台(单实例 second-instance 处理)

Open
#569 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

提交前确认 · Pre-submission checklist
  • 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate. (#325 是麒麟/Linux 最小化后频繁弹出,根因不同;问题是 Windows 外部探测触发)
  • 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category

UI / 界面体验 · UI / UX

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

影响体验 · Major (功能可用但体验受损 / works but degraded)

复现频率 · Reproducibility

必现 · Always

问题描述 · Description

Windows 下,任何外部进程调用一次 ZCode.exe --version(例如第三方工具做"客户端已安装/版本"探测),由于 Electron 单实例锁,新进程会在已有主实例上触发 second-instance 事件,主进程随即执行 n.restore(); n.show(); n.focus(),导致已打开的 ZCode 窗口从后台跳回前台,抢走当前焦点。

实测:安装 EasyCLIProxyAPI 后它每 ~20 秒探测一次 ZCode.exe --version,ZCode 会话窗口大约每 20 秒就从后台跳回最前面,干扰任何其他窗口工作。

主进程源码(app.asar,second-instance 事件处理器)逻辑:

ye.on("second-instance", (e, t, r, o) => {
  ...
  let n = yt()[0];
  n && (n.isMinimized() && n.restore(), n.isVisible() || n.show(), n.focus());
});

即使新实例进程只是 --version 探测且立即退出,只要它走了 app.requestSingleInstanceLock(),就必然触发上述前台逻辑。

复现步骤 · Steps to reproduce
  1. Windows 10/11 安装并运行 ZCode 桌面版,打开任意会话窗口
  2. 另开一个窗口(如记事本/浏览器),让 ZCode 处于后台
  3. 用外部工具执行一次 "C:\path\to\ZCode.exe" --version(探测性调用,进程约 2 秒后退出)
  4. 观察:ZCode 主窗口自动跳到最前面并抢焦点;若探测被周期性执行(如 EasyCLIProxyAPI 每 20 秒),则窗口每 20 秒抢一次前台
期望表现 · Expected behavior

--version 这种只读探测(以及任何不带"打开工作区/窗口"意图的 second instance 参数)不应触发主窗口 show()/focus(),即:

  • 探测进程应输出版本号后直接退出,不干扰已运行实例的窗口状态
  • second-instance 处理器只有在携带真实意图(如 deep-link open workspace)时才 restore/show/focus;其余情况若窗口已存在且非最小化,应保持原状
实际表现 · Actual behavior

被外部探测时,ZCode 主窗口总是被 restore(); show(); focus(),从后台跳回前台,持续打断用户当前正在使用的其他窗口。多实例工具(CLI 探测、客户端发现类工具)会放大该问题为周期性抢焦点。

对 EasyCLIProxyAPI 实证(每 20 秒)的进程追踪:

12:09:10 NEW pid=59416 ppid=5312 parent=EasyCLIProxyAPI cmd="...ZCode.exe" --version
12:09:29 NEW pid=53112 ppid=5312 parent=EasyCLIProxyAPI cmd="...ZCode.exe" --version
12:09:45 NEW pid=8884  ppid=5312 parent=EasyCLIProxyAPI cmd="...ZCode.exe" --version
...
ZCode 版本 · ZCode version

3.11.2 (desktop, windows-x64)

设备 / 系统 / 浏览器 · Device / OS / Browser

Windows 10 19045 x64(桌面版,非打包 dev 构建;非标准安装路径 E:\soft\ZCode,但同目录链接探测亦可复现)

截图 / 录屏 / 日志 · Screenshots / Recordings / Logs

日志证据(~/.zcode/v2/logs/*.log):每次探测触发的主实例 [main] 日志无 second-instance 专属条目,但进程树可观测到:探测进程 crashpad/gpu 子进程完整启动后约 2 秒退出,同时主窗口期前台。如需完整日志压缩包可补充(含脱敏处理)。


补充建议:若判断 --version 处理可在 app.requestSingleInstanceLock() 之前提前返回(如 app.commandLine.hasSwitch("version") / Node argv 检查后直接 app.exit(0)),可顺带避免每次探测都完整冷启动 Electron(crashpad/gpu/network 子进程),也减少探测对 CPU/磁盘的消耗。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the Electron main-process second-instance handler and the startup path around app.requestSingleInstanceLock(), using the reported --version invocation as the first case to trace. Verify the change on Windows with an already-open, background ZCode window; done means version probing exits without restoring, showing, or focusing the existing window, while genuine open-workspace intents still work.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.