diff --git a/electron/services/wcdbCore.ts b/electron/services/wcdbCore.ts index 6144726..e3c9baf 100644 --- a/electron/services/wcdbCore.ts +++ b/electron/services/wcdbCore.ts @@ -1,6 +1,12 @@ import { join, dirname, basename } from 'path' import { appendFileSync, existsSync, mkdirSync, readdirSync, statSync, readFileSync } from 'fs' +// DLL 初始化错误信息,用于帮助用户诊断问题 +let lastDllInitError: string | null = null +export function getLastDllInitError(): string | null { + return lastDllInitError +} + export class WcdbCore { private resourcesPath: string | null = null private userDataPath: string | null = null @@ -208,6 +214,31 @@ export class WcdbCore { return false } + // 关键修复:显式预加载依赖库 WCDB.dll 和 SDL2.dll + // Windows 加载器默认不会查找子目录中的依赖,必须先将其加载到内存 + // 这可以解决部分用户因为 VC++ 运行时或 DLL 依赖问题导致的闪退 + const dllDir = dirname(dllPath) + const wcdbCorePath = join(dllDir, 'WCDB.dll') + if (existsSync(wcdbCorePath)) { + try { + this.koffi.load(wcdbCorePath) + this.writeLog('预加载 WCDB.dll 成功') + } catch (e) { + console.warn('预加载 WCDB.dll 失败(可能不是致命的):', e) + this.writeLog(`预加载 WCDB.dll 失败: ${String(e)}`) + } + } + const sdl2Path = join(dllDir, 'SDL2.dll') + if (existsSync(sdl2Path)) { + try { + this.koffi.load(sdl2Path) + this.writeLog('预加载 SDL2.dll 成功') + } catch (e) { + console.warn('预加载 SDL2.dll 失败(可能不是致命的):', e) + this.writeLog(`预加载 SDL2.dll 失败: ${String(e)}`) + } + } + this.lib = this.koffi.load(dllPath) // 定义类型 @@ -362,9 +393,20 @@ export class WcdbCore { } this.initialized = true + lastDllInitError = null return true } catch (e) { - console.error('WCDB 初始化异常:', e) + const errorMsg = e instanceof Error ? e.message : String(e) + console.error('WCDB 初始化异常:', errorMsg) + this.writeLog(`WCDB 初始化异常: ${errorMsg}`, true) + lastDllInitError = errorMsg + // 检查是否是常见的 VC++ 运行时缺失错误 + if (errorMsg.includes('126') || errorMsg.includes('找不到指定的模块') || + errorMsg.includes('The specified module could not be found')) { + lastDllInitError = '可能缺少 Visual C++ 运行时库。请安装 Microsoft Visual C++ Redistributable (x64)。' + } else if (errorMsg.includes('193') || errorMsg.includes('不是有效的 Win32 应用程序')) { + lastDllInitError = 'DLL 架构不匹配。请确保使用 64 位版本的应用程序。' + } return false } } @@ -391,7 +433,9 @@ export class WcdbCore { if (!this.initialized) { const initOk = await this.initialize() if (!initOk) { - return { success: false, error: 'WCDB 初始化失败' } + // 返回更详细的错误信息,帮助用户诊断问题 + const detailedError = lastDllInitError || 'WCDB 初始化失败' + return { success: false, error: detailedError } } } diff --git a/electron/services/wcdbService.ts b/electron/services/wcdbService.ts index 7628c67..bdcd2bc 100644 --- a/electron/services/wcdbService.ts +++ b/electron/services/wcdbService.ts @@ -58,12 +58,24 @@ export class WcdbService { }) this.worker.on('error', (err) => { - // Worker error + // Worker 发生错误,需要 reject 所有 pending promises + console.error('WCDB Worker 错误:', err) + const errorMsg = err instanceof Error ? err.message : String(err) + for (const [id, p] of this.pending) { + p.reject(new Error(`Worker 错误: ${errorMsg}`)) + } + this.pending.clear() }) this.worker.on('exit', (code) => { + // Worker 退出,需要 reject 所有 pending promises if (code !== 0) { - // Worker exited with error + console.error('WCDB Worker 异常退出,退出码:', code) + const errorMsg = `Worker 异常退出 (退出码: ${code})。可能是 DLL 加载失败,请检查是否安装了 Visual C++ Redistributable。` + for (const [id, p] of this.pending) { + p.reject(new Error(errorMsg)) + } + this.pending.clear() } this.worker = null }) diff --git a/src/App.tsx b/src/App.tsx index 77aa32f..98fe58b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -202,10 +202,22 @@ function App() { } } else { console.log('自动连接失败:', result.error) + // 如果错误信息包含 VC++ 或 DLL 相关内容,不清除配置,只提示用户 + // 其他错误可能需要重新配置 + const errorMsg = result.error || '' + if (errorMsg.includes('Visual C++') || + errorMsg.includes('DLL') || + errorMsg.includes('Worker') || + errorMsg.includes('126') || + errorMsg.includes('模块')) { + console.warn('检测到可能的运行时依赖问题:', errorMsg) + // 不清除配置,让用户安装 VC++ 后重试 + } } } } catch (e) { console.error('自动连接出错:', e) + // 捕获异常但不清除配置,防止循环重新引导 } }