diff --git a/electron/main.ts b/electron/main.ts index 46b96a9..7996fed 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -258,7 +258,9 @@ function createWindow(options: { autoShow?: boolean } = {}) { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) const win = new BrowserWindow({ width: 1400, @@ -381,7 +383,9 @@ function createAgreementWindow() { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) const isDark = nativeTheme.shouldUseDarkColors @@ -431,7 +435,9 @@ function createSplashWindow(): BrowserWindow { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) splashWindow = new BrowserWindow({ width: 760, @@ -502,7 +508,9 @@ function createOnboardingWindow() { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) onboardingWindow = new BrowserWindow({ width: 960, @@ -548,7 +556,9 @@ function createVideoPlayerWindow(videoPath: string, videoWidth?: number, videoHe const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) // 获取屏幕尺寸 const { screen } = require('electron') @@ -646,7 +656,9 @@ function createImageViewerWindow(imagePath: string, liveVideoPath?: string) { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) const win = new BrowserWindow({ width: 900, @@ -704,7 +716,9 @@ function createChatHistoryWindow(sessionId: string, messageId: number) { const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) // 根据系统主题设置窗口背景色 const isDark = nativeTheme.shouldUseDarkColors @@ -779,7 +793,9 @@ function createSessionChatWindow(sessionId: string, options?: OpenSessionChatWin const isDev = !!process.env.VITE_DEV_SERVER_URL const iconPath = isDev ? join(__dirname, '../public/icon.ico') - : join(process.resourcesPath, 'icon.ico') + : (process.platform === 'darwin' + ? join(process.resourcesPath, 'icon.icns') + : join(process.resourcesPath, 'icon.ico')) const isDark = nativeTheme.shouldUseDarkColors diff --git a/electron/services/keyServiceMac.ts b/electron/services/keyServiceMac.ts index 006e7cf..e612b8c 100644 --- a/electron/services/keyServiceMac.ts +++ b/electron/services/keyServiceMac.ts @@ -178,14 +178,14 @@ export class KeyServiceMac { try { // 优先使用 pgrep,避免 ps 的 comm 列被截断导致识别失败 try { - const { stdout } = await execFileAsync('pgrep', ['-x', 'WeChat']) + const { stdout } = await execFileAsync('/usr/bin/pgrep', ['-x', 'WeChat']) const ids = stdout.split(/\r?\n/).map(s => parseInt(s.trim(), 10)).filter(n => Number.isFinite(n) && n > 0) if (ids.length > 0) return Math.max(...ids) } catch { // ignore and fallback to ps } - const { stdout } = await execFileAsync('ps', ['-A', '-o', 'pid,comm,command']) + const { stdout } = await execFileAsync('/bin/ps', ['-A', '-o', 'pid,comm,command']) const lines = stdout.split('\n').slice(1) const candidates: Array<{ pid: number; command: string }> = [] @@ -231,7 +231,7 @@ export class KeyServiceMac { const pid = await this.getWeChatPid() onStatus?.(`已找到微信进程 PID=${pid},正在定位目标函数...`, 0) // 最佳努力清理同路径残留 helper(普通权限) - try { await execFileAsync('pkill', ['-f', helperPath], { timeout: 2000 }) } catch { } + try { await execFileAsync('/usr/bin/pkill', ['-f', helperPath], { timeout: 2000 }) } catch { } return await new Promise((resolve, reject) => { // xkey_helper 参数协议:helper [timeout_ms] diff --git a/package.json b/package.json index 99b2c94..c3bce01 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,8 @@ "hardenedRuntime": false, "gatekeeperAssess": false, "entitlements": "electron/entitlements.mac.plist", - "entitlementsInherit": "electron/entitlements.mac.plist" + "entitlementsInherit": "electron/entitlements.mac.plist", + "icon": "resources/icon.icns" }, "win": { "target": [ @@ -120,6 +121,10 @@ { "from": "electron/assets/wasm/", "to": "assets/wasm/" + }, + { + "from": "resources/icon.icns", + "to": "icon.icns" } ], "files": [ @@ -150,6 +155,7 @@ "from": "resources/vcruntime140_1.dll", "to": "." } - ] + ], + "icon": "resources/icon.icns" } } diff --git a/resources/icon.icns b/resources/icon.icns new file mode 100644 index 0000000..70df606 Binary files /dev/null and b/resources/icon.icns differ