Skip to content

[windows] hotkey hook 永远 starting 时启动 gate 死锁,主窗口卡 "正在启动" 灰屏 #163

Description

@appergb

现象

Windows 上若 OS 拒绝低层键盘 hook 安装(`SetWindowsHookExW(WH_KEYBOARD_LL)` 因 UAC / 第三方安全软件 / 防御性策略而长期 starting),OpenLess 主窗口永久卡在 "正在启动" 灰屏,UI 永远不出来——用户点 OpenLess.exe 后看到一个空 shell,没法进设置改 hotkey、没法看错误。

复现

人为复现路径:

  1. Windows 上的反作弊/EDR 安全软件 block 第三方进程的 keyboard hook
  2. 或测试用 `SetWindowsHookExW` mock 永远返回 NULL
  3. 启动 OpenLess
  4. 观察:UI 卡 StartupShell 灰屏不动,无超时不弹错误

实际场景:用户报反馈"打开 OpenLess 看到一片空白不动"——根因可能就是这条。

根因

App.tsx:60 Windows 启动 gate 用无限轮询查 hotkey status:

```tsx
const pollHotkeyStatus = async () => {
while (!cancelled) {
const status = await getHotkeyStatus();
if (cancelled) return;
if (status.state !== 'starting') {
setGate('ready');
return;
}
await new Promise(resolve => window.setTimeout(resolve, 200));
}
};
```

  • 只在 `state !== 'starting'` 才 break
  • 后端 `hotkey_supervisor_loop` 永远 starting(hook 安装失败但持续重试)→ 前端永远 200ms 一次 ping,永不退出
  • catch 分支会兜底但 try 内 getHotkeyStatus() 不抛错只回 'starting' 时,永远进不去 catch

影响

  • 平台:仅 Windows(macOS / Linux 走不同 gate 逻辑)
  • 频率:边缘场景(依赖第三方安全软件配置),但当下没有任何超时保护
  • 用户损失:完全无法使用 OpenLess,且看不到错误信息

建议 fix

加最大轮询次数 + 超时 fallback:

```tsx
const MAX_POLL = 50; // 50 * 200ms = 10s
let attempts = 0;

while (!cancelled && attempts < MAX_POLL) {
attempts++;
const status = await getHotkeyStatus();
if (cancelled) return;
if (status.state !== 'starting') {
setGate('ready');
return;
}
await new Promise(resolve => window.setTimeout(resolve, 200));
}

// 超时强 setGate('ready'),让用户进 Permissions 页看错误
if (!cancelled) {
console.warn('[startup] hotkey gate timed out after 10s');
setGate('ready');
}
```

Permissions 页应该已经能显示 hotkey_status 的 lastError + 引导用户检查权限/安全软件。先让用户能看到这个页面。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions