mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
修复图片解密 修复密钥获取
This commit is contained in:
@@ -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) => {
|
return keyService.autoGetImageKey(manualDir, (message) => {
|
||||||
event.sender.send('key:imageKeyStatus', { message })
|
event.sender.send('key:imageKeyStatus', { message })
|
||||||
})
|
}, wxid)
|
||||||
})
|
})
|
||||||
|
|
||||||
// HTTP API 服务
|
// HTTP API 服务
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
// 密钥获取
|
// 密钥获取
|
||||||
key: {
|
key: {
|
||||||
autoGetDbKey: () => ipcRenderer.invoke('key:autoGetDbKey'),
|
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) => {
|
onDbKeyStatus: (callback: (payload: { message: string; level: number }) => void) => {
|
||||||
ipcRenderer.on('key:dbKeyStatus', (_, payload) => callback(payload))
|
ipcRenderer.on('key:dbKeyStatus', (_, payload) => callback(payload))
|
||||||
return () => ipcRenderer.removeAllListeners('key:dbKeyStatus')
|
return () => ipcRenderer.removeAllListeners('key:dbKeyStatus')
|
||||||
|
|||||||
@@ -15,8 +15,16 @@ function getStaticFfmpegPath(): string | null {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const ffmpegStatic = require('ffmpeg-static')
|
const ffmpegStatic = require('ffmpeg-static')
|
||||||
|
|
||||||
if (typeof ffmpegStatic === 'string' && existsSync(ffmpegStatic)) {
|
if (typeof ffmpegStatic === 'string') {
|
||||||
return ffmpegStatic
|
// 修复:如果路径包含 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: 手动构建路径(开发环境)
|
// 方法2: 手动构建路径(开发环境)
|
||||||
|
|||||||
@@ -651,7 +651,8 @@ export class KeyService {
|
|||||||
|
|
||||||
async autoGetImageKey(
|
async autoGetImageKey(
|
||||||
manualDir?: string,
|
manualDir?: string,
|
||||||
onProgress?: (message: string) => void
|
onProgress?: (message: string) => void,
|
||||||
|
wxidParam?: string
|
||||||
): Promise<ImageKeyResult> {
|
): Promise<ImageKeyResult> {
|
||||||
if (!this.ensureWin32()) return { success: false, error: '仅支持 Windows' }
|
if (!this.ensureWin32()) return { success: false, error: '仅支持 Windows' }
|
||||||
if (!this.ensureLoaded()) return { success: false, error: 'wx_key.dll 未加载' }
|
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)
|
const codes: number[] = accounts[0].keys.map((k: any) => k.code)
|
||||||
console.log('[ImageKey] codes:', codes, 'DLL wxids:', accounts.map((a: any) => a.wxid))
|
console.log('[ImageKey] codes:', codes, 'DLL wxids:', accounts.map((a: any) => a.wxid))
|
||||||
|
|
||||||
// 从 manualDir 提取前端已配置好的正确 wxid
|
// 优先级: 1. 直接传入的wxidParam 2. 从manualDir提取 3. DLL返回的wxid(可能是unknown)
|
||||||
// 格式: "D:\weixin\xwechat_files\wxid_xxx_1234" → "wxid_xxx_1234"
|
|
||||||
let targetWxid = ''
|
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() ?? ''
|
const dirName = manualDir.replace(/[\\/]+$/, '').split(/[\\/]/).pop() ?? ''
|
||||||
if (dirName.startsWith('wxid_')) {
|
if (dirName.startsWith('wxid_')) {
|
||||||
targetWxid = dirName
|
targetWxid = dirName
|
||||||
|
console.log('[ImageKey] 从 manualDir 提取 wxid:', targetWxid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 方案3: 回退到 DLL 发现的第一个(可能是 unknown)
|
||||||
if (!targetWxid) {
|
if (!targetWxid) {
|
||||||
// 无法从 manualDir 提取 wxid,回退到 DLL 发现的第一个
|
|
||||||
targetWxid = accounts[0].wxid
|
targetWxid = accounts[0].wxid
|
||||||
console.log('[ImageKey] 无法从 manualDir 提取 wxid,使用 DLL 发现的:', targetWxid)
|
console.log('[ImageKey] 无法获取 wxid,使用 DLL 发现的:', targetWxid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanWxid: 截断到第二个下划线,与 xkey 算法一致
|
// CleanWxid: 截断到第二个下划线,与 xkey 算法一致
|
||||||
|
|||||||
Binary file not shown.
@@ -779,7 +779,7 @@ function SettingsPage() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const accountPath = wxid ? `${dbPath}/${wxid}` : dbPath;
|
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 (result.success && result.aesKey) {
|
||||||
if (typeof result.xorKey === 'number') {
|
if (typeof result.xorKey === 'number') {
|
||||||
setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`)
|
setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`)
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ function WelcomePage({ standalone = false }: WelcomePageProps) {
|
|||||||
try {
|
try {
|
||||||
// 拼接完整的账号目录,确保 KeyService 能准确找到模板文件
|
// 拼接完整的账号目录,确保 KeyService 能准确找到模板文件
|
||||||
const accountPath = wxid ? `${dbPath}/${wxid}` : dbPath
|
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 (result.success && result.aesKey) {
|
||||||
if (typeof result.xorKey === 'number') {
|
if (typeof result.xorKey === 'number') {
|
||||||
setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`)
|
setImageXorKey(`0x${result.xorKey.toString(16).toUpperCase().padStart(2, '0')}`)
|
||||||
|
|||||||
2
src/types/electron.d.ts
vendored
2
src/types/electron.d.ts
vendored
@@ -66,7 +66,7 @@ export interface ElectronAPI {
|
|||||||
}
|
}
|
||||||
key: {
|
key: {
|
||||||
autoGetDbKey: () => Promise<{ success: boolean; key?: string; error?: string; logs?: string[] }>
|
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
|
onDbKeyStatus: (callback: (payload: { message: string; level: number }) => void) => () => void
|
||||||
onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void
|
onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user