From 44dbb9421f2868b102c6a77cf29e425b39f4363a Mon Sep 17 00:00:00 2001 From: razzh Date: Sat, 11 Apr 2026 17:07:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Windows=20=E4=B8=8B=20bun=20dev=20?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=B4=A9=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. dev:kill / dev:electron 脚本使用了 pkill 和 sleep,Windows 不支持, 替换为跨平台的 bun 脚本(scripts/dev-kill.ts、scripts/sleep.ts) 2. electronmon 热重载时在 app.isReady() 之前触发 before-quit, 导致 globalShortcut.unregisterAll() 抛出 uncaught exception(exit code 37), 添加 app.isReady() 守卫修复 --- apps/electron/package.json | 4 ++-- apps/electron/scripts/dev-kill.ts | 24 +++++++++++++++++++ apps/electron/scripts/sleep.ts | 6 +++++ .../src/main/lib/global-shortcut-service.ts | 6 +++-- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 apps/electron/scripts/dev-kill.ts create mode 100644 apps/electron/scripts/sleep.ts diff --git a/apps/electron/package.json b/apps/electron/package.json index 441b0b76..a4a48ed0 100644 --- a/apps/electron/package.json +++ b/apps/electron/package.json @@ -13,8 +13,8 @@ "dev": "concurrently -k -n vite,electron -c blue,green \"bun run dev:vite\" \"bun run dev:electron\"", "dev:split": "bash scripts/dev-split.sh", "dev:vite": "vite dev", - "dev:kill": "pkill -f 'electronmon \\.' 2>/dev/null; pkill -f 'electron.*dist/main' 2>/dev/null; sleep 0.5; true", - "dev:electron": "bun run dev:kill && bun run build:main && bun run build:preload && bun run build:resources && sleep 2 && concurrently -k -n main,preload,app -c yellow,magenta,cyan \"bun run watch:main\" \"bun run watch:preload\" \"bunx electronmon .\"", + "dev:kill": "bun run scripts/dev-kill.ts", + "dev:electron": "bun run dev:kill && bun run build:main && bun run build:preload && bun run build:resources && bun run scripts/sleep.ts 2 && concurrently -k -n main,preload,app -c yellow,magenta,cyan \"bun run watch:main\" \"bun run watch:preload\" \"bunx electronmon .\"", "build:main": "esbuild src/main/index.ts --bundle --platform=node --format=cjs --outfile=dist/main.cjs --external:electron --external:@anthropic-ai/claude-agent-sdk", "build:preload": "esbuild src/preload/index.ts --bundle --platform=node --format=cjs --outfile=dist/preload.cjs --external:electron", "watch:main": "esbuild src/main/index.ts --bundle --platform=node --format=cjs --outfile=dist/main.cjs --external:electron --external:@anthropic-ai/claude-agent-sdk --watch=forever", diff --git a/apps/electron/scripts/dev-kill.ts b/apps/electron/scripts/dev-kill.ts new file mode 100644 index 00000000..708b5602 --- /dev/null +++ b/apps/electron/scripts/dev-kill.ts @@ -0,0 +1,24 @@ +/** + * 跨平台清理残留的 electronmon / electron 进程 + * 替代 pkill(Windows 不支持) + */ +import { execSync } from 'child_process' + +const isWin = process.platform === 'win32' + +function kill(pattern: string): void { + try { + if (isWin) { + // Windows: taskkill 按进程名 + execSync(`taskkill /F /IM ${pattern} 2>nul`, { stdio: 'ignore' }) + } else { + // Unix: pkill 按模式匹配 + execSync(`pkill -f '${pattern}' 2>/dev/null`, { stdio: 'ignore' }) + } + } catch { + // 没有匹配进程,忽略 + } +} + +kill(isWin ? 'electronmon.exe' : 'electronmon \\.') +kill(isWin ? 'electron.exe' : 'electron.*dist/main') diff --git a/apps/electron/scripts/sleep.ts b/apps/electron/scripts/sleep.ts new file mode 100644 index 00000000..b5f695f3 --- /dev/null +++ b/apps/electron/scripts/sleep.ts @@ -0,0 +1,6 @@ +/** + * 跨平台 sleep 命令 + * 用法: bun run scripts/sleep.ts + */ +const seconds = Number(process.argv[2]) || 2 +await new Promise((resolve) => setTimeout(resolve, seconds * 1000)) diff --git a/apps/electron/src/main/lib/global-shortcut-service.ts b/apps/electron/src/main/lib/global-shortcut-service.ts index fa8371ea..08d88caf 100644 --- a/apps/electron/src/main/lib/global-shortcut-service.ts +++ b/apps/electron/src/main/lib/global-shortcut-service.ts @@ -9,7 +9,7 @@ * - 主进程:globalShortcut.register,系统级生效 */ -import { globalShortcut } from 'electron' +import { app, globalShortcut } from 'electron' import { getSettings } from './settings-service' /** 全局快捷键 ID → 回调映射 */ @@ -124,7 +124,9 @@ export function reregisterAllGlobalShortcuts(): Record { * 在 app.will-quit / before-quit 时调用。 */ export function unregisterAllGlobalShortcuts(): void { - globalShortcut.unregisterAll() + if (app.isReady()) { + globalShortcut.unregisterAll() + } registeredAccelerators.clear() globalCallbacks.clear() console.log('[全局快捷键] 已注销所有')