diff --git a/electron/main.ts b/electron/main.ts index 8036e98..91c6b14 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -1533,10 +1533,10 @@ function registerIpcHandlers() { }) }) - ipcMain.handle('key:autoGetImageKey', async (event, manualDir?: string) => { + ipcMain.handle('key:autoGetImageKey', async (event, manualDir?: string, wxid?: string) => { return keyService.autoGetImageKey(manualDir, (message) => { event.sender.send('key:imageKeyStatus', { message }) - }) + }, wxid) }) // HTTP API 服务 diff --git a/electron/preload.ts b/electron/preload.ts index 76ad1c7..e81a267 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -113,7 +113,7 @@ contextBridge.exposeInMainWorld('electronAPI', { // 密钥获取 key: { autoGetDbKey: () => ipcRenderer.invoke('key:autoGetDbKey'), - autoGetImageKey: (manualDir?: string) => ipcRenderer.invoke('key:autoGetImageKey', manualDir), + autoGetImageKey: (manualDir?: string, wxid?: string) => ipcRenderer.invoke('key:autoGetImageKey', manualDir, wxid), onDbKeyStatus: (callback: (payload: { message: string; level: number }) => void) => { ipcRenderer.on('key:dbKeyStatus', (_, payload) => callback(payload)) return () => ipcRenderer.removeAllListeners('key:dbKeyStatus') diff --git a/electron/services/imageDecryptService.ts b/electron/services/imageDecryptService.ts index b1c9478..13dce67 100644 --- a/electron/services/imageDecryptService.ts +++ b/electron/services/imageDecryptService.ts @@ -15,8 +15,16 @@ function getStaticFfmpegPath(): string | null { // eslint-disable-next-line @typescript-eslint/no-var-requires const ffmpegStatic = require('ffmpeg-static') - if (typeof ffmpegStatic === 'string' && existsSync(ffmpegStatic)) { - return ffmpegStatic + if (typeof ffmpegStatic === 'string') { + // 修复:如果路径包含 app.asar(打包后),自动替换为 app.asar.unpacked + let fixedPath = ffmpegStatic + if (fixedPath.includes('app.asar') && !fixedPath.includes('app.asar.unpacked')) { + fixedPath = fixedPath.replace('app.asar', 'app.asar.unpacked') + } + + if (existsSync(fixedPath)) { + return fixedPath + } } // 方法2: 手动构建路径(开发环境) diff --git a/electron/services/keyService.ts b/electron/services/keyService.ts index c487d99..3168f1c 100644 --- a/electron/services/keyService.ts +++ b/electron/services/keyService.ts @@ -651,7 +651,8 @@ export class KeyService { async autoGetImageKey( manualDir?: string, - onProgress?: (message: string) => void + onProgress?: (message: string) => void, + wxidParam?: string ): Promise { if (!this.ensureWin32()) return { success: false, error: '仅支持 Windows' } if (!this.ensureLoaded()) return { success: false, error: 'wx_key.dll 未加载' } @@ -683,20 +684,29 @@ export class KeyService { const codes: number[] = accounts[0].keys.map((k: any) => k.code) console.log('[ImageKey] codes:', codes, 'DLL wxids:', accounts.map((a: any) => a.wxid)) - // 从 manualDir 提取前端已配置好的正确 wxid - // 格式: "D:\weixin\xwechat_files\wxid_xxx_1234" → "wxid_xxx_1234" + // 优先级: 1. 直接传入的wxidParam 2. 从manualDir提取 3. DLL返回的wxid(可能是unknown) let targetWxid = '' - if (manualDir) { + + // 方案1: 直接使用传入的wxidParam(最优先) + if (wxidParam && wxidParam.startsWith('wxid_')) { + targetWxid = wxidParam + console.log('[ImageKey] 使用直接传入的 wxid:', targetWxid) + } + + // 方案2: 从 manualDir 提取前端已配置好的正确 wxid + // 格式: "D:\weixin\xwechat_files\wxid_xxx_1234" → "wxid_xxx_1234" + if (!targetWxid && manualDir) { const dirName = manualDir.replace(/[\\/]+$/, '').split(/[\\/]/).pop() ?? '' if (dirName.startsWith('wxid_')) { targetWxid = dirName + console.log('[ImageKey] 从 manualDir 提取 wxid:', targetWxid) } } + // 方案3: 回退到 DLL 发现的第一个(可能是 unknown) if (!targetWxid) { - // 无法从 manualDir 提取 wxid,回退到 DLL 发现的第一个 targetWxid = accounts[0].wxid - console.log('[ImageKey] 无法从 manualDir 提取 wxid,使用 DLL 发现的:', targetWxid) + console.log('[ImageKey] 无法获取 wxid,使用 DLL 发现的:', targetWxid) } // CleanWxid: 截断到第二个下划线,与 xkey 算法一致 diff --git a/resources/wx_key.dll b/resources/wx_key.dll index e03975d..30ddb52 100644 Binary files a/resources/wx_key.dll and b/resources/wx_key.dll differ diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 154d528..00da7d9 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -779,7 +779,7 @@ function SettingsPage() { try { const accountPath = wxid ? `${dbPath}/${wxid}` : dbPath; - const result = await window.electronAPI.key.autoGetImageKey(accountPath) + const result = await window.electronAPI.key.autoGetImageKey(accountPath, wxid) if (result.success && result.aesKey) { if (typeof result.xorKey === 'number') { setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`) diff --git a/src/pages/WelcomePage.tsx b/src/pages/WelcomePage.tsx index 9a43cef..0c94d9c 100644 --- a/src/pages/WelcomePage.tsx +++ b/src/pages/WelcomePage.tsx @@ -320,7 +320,7 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { try { // 拼接完整的账号目录,确保 KeyService 能准确找到模板文件 const accountPath = wxid ? `${dbPath}/${wxid}` : dbPath - const result = await window.electronAPI.key.autoGetImageKey(accountPath) + const result = await window.electronAPI.key.autoGetImageKey(accountPath, wxid) if (result.success && result.aesKey) { if (typeof result.xorKey === 'number') { setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`) diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index ee0c0f1..ba9b10b 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -66,7 +66,7 @@ export interface ElectronAPI { } key: { autoGetDbKey: () => Promise<{ success: boolean; key?: string; error?: string; logs?: string[] }> - autoGetImageKey: (manualDir?: string) => Promise<{ success: boolean; xorKey?: number; aesKey?: string; error?: string }> + autoGetImageKey: (manualDir?: string, wxid?: string) => Promise<{ success: boolean; xorKey?: number; aesKey?: string; error?: string }> onDbKeyStatus: (callback: (payload: { message: string; level: number }) => void) => () => void onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void }