const { app, BrowserWindow, ipcMain } = require('electron') const path = require('path') const fs = require('fs') const os = require('os') // 设置进程编码,确保中文正常显示 process.env.LANG = 'zh_CN.UTF-8' process.env.LC_ALL = 'zh_CN.UTF-8' // 获取项目根目录绝对路径 const appRoot = path.resolve(__dirname, '../..') console.log('Application root:', appRoot) // 获取本地IP地址 function getLocalIPAddresses() { try { const interfaces = os.networkInterfaces() const addresses = [] for (const name of Object.keys(interfaces)) { for (const interface of interfaces[name]) { // 跳过内部地址和非IPv4地址 if (interface.family === 'IPv4' && !interface.internal) { addresses.push({ name: name, address: interface.address, netmask: interface.netmask, family: interface.family }) } } } // 优先返回非回环地址 const nonLoopback = addresses.filter(addr => addr.address !== '127.0.0.1') return nonLoopback.length > 0 ? nonLoopback[0] : addresses[0] || null } catch (error) { console.error('获取本地IP地址失败:', error) return null } } let mainWindow let errorLogCount = 0 let logFilePath // 检查是否为开发环境 const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged console.log('Development environment:', isDev) // 初始化日志系统 function initLogging() { try { // 创建日志目录 const logDir = path.join(app.getPath('userData'), 'logs') if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }) } // 设置日志文件路径 const timestamp = new Date().toISOString().split('T')[0] logFilePath = path.join(logDir, `gofaster-${timestamp}.log`) // 重定向控制台输出到日志文件,设置UTF-8编码 const logStream = fs.createWriteStream(logFilePath, { flags: 'a', encoding: 'utf8' }) // 重写console.log const originalLog = console.log console.log = function(...args) { const timestamp = new Date().toISOString() const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg) ).join(' ') logStream.write(`[${timestamp}] [INFO] ${message}\n`) originalLog.apply(console, args) } // 重写console.error const originalError = console.error console.error = function(...args) { const timestamp = new Date().toISOString() const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg) ).join(' ') errorLogCount++ logStream.write(`[${timestamp}] [ERROR] ${message}\n`) originalError.apply(console, args) // 通知渲染进程错误计数更新 if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.webContents.send('error-log-updated', { count: errorLogCount }) } } // 重写console.warn const originalWarn = console.warn console.warn = function(...args) { const timestamp = new Date().toISOString() const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg) ).join(' ') logStream.write(`[${timestamp}] [WARN] ${message}\n`) originalWarn.apply(console, args) } console.log('日志系统已初始化,日志文件:', logFilePath) } catch (error) { console.error('初始化日志系统失败:', error) } } // 开发环境热重载 - 只在非watch模式下启用 if (isDev && !process.argv.includes('--watch')) { try { // 修复热重载配置 require('electron-reload')(appRoot, { electron: path.join(__dirname, '..', '..', 'node_modules', 'electron', 'dist', 'electron.exe'), hardResetMethod: 'exit', // 添加更稳定的配置 forceHardReset: true, ignored: [ /node_modules|[\/\\]\./, /dist|[\/\\]\./, /\.git|[\/\\]\./ ] }); console.log('Hot reload enabled'); } catch (error) { console.log('Hot reload failed:', error.message); } } // 监听文件变化(用于watch模式) if (isDev && process.argv.includes('--watch')) { console.log('Watch mode enabled, monitoring file changes...'); // 监听dist目录变化 const distPath = path.join(appRoot, 'dist/renderer'); if (fs.existsSync(distPath)) { let reloadTimeout = null; fs.watch(distPath, { recursive: true }, (eventType, filename) => { if (filename && mainWindow && !mainWindow.isDestroyed()) { // 添加防抖机制,避免频繁重载 if (reloadTimeout) { clearTimeout(reloadTimeout); } reloadTimeout = setTimeout(() => { try { console.log(`File changed: ${filename}, reloading page...`); mainWindow.reload(); } catch (error) { console.log('Page reload failed:', error.message); } }, 500); // 500ms防抖延迟 } }); } } function createWindow() { try { mainWindow = new BrowserWindow({ width: 1200, height: 800, autoHideMenuBar: true, webPreferences: { nodeIntegration: false, contextIsolation: true, enableRemoteModule: false, preload: path.join(appRoot, 'src/preload.js'), // 强化安全配置 webSecurity: true, allowRunningInsecureContent: false, experimentalFeatures: false, // 禁用Node.js集成 nodeIntegrationInWorker: false, nodeIntegrationInSubFrames: false, // 沙箱模式 sandbox: false, // 保持false以支持preload脚本 // 禁用eval相关功能 enableBlinkFeatures: '', disableBlinkFeatures: 'Auxclick' }, // 添加字体配置,确保中文正常显示 titleBarStyle: 'default', show: false // 先隐藏窗口,等加载完成后再显示 }) console.log('Main window created'); // 开发环境下抑制安全警告 if (isDev) { mainWindow.webContents.on('did-frame-finish-load', () => { // 移除有问题的JavaScript执行,避免IPC通信错误 console.log('Page loaded, DevTools ready'); // 简化JavaScript注入,避免序列化错误 mainWindow.webContents.executeJavaScript(` // 重写console.warn和console.error来抑制特定警告 const originalWarn = console.warn; const originalError = console.error; console.warn = function(...args) { const message = args.join(' '); if (message.includes('Electron Security Warning') || message.includes('Insecure Content-Security-Policy') || message.includes('unsafe-eval')) { return; // 抑制这些警告 } originalWarn.apply(console, args); }; console.error = function(...args) { const message = args.join(' '); if (message.includes('Electron Security Warning') || message.includes('Insecure Content-Security-Policy') || message.includes('unsafe-eval')) { return; // 抑制这些警告 } originalError.apply(console, args); }; console.log('Console warning suppression enabled'); `).catch(err => { console.log('JavaScript injection failed:', err.message); // 注入失败不影响应用运行 }); }); // 添加页面加载错误处理 mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL) => { console.log('Page load failed:', errorDescription); // 可以在这里添加重试逻辑 }); // 添加渲染进程崩溃处理 mainWindow.webContents.on('render-process-gone', (event, details) => { console.log('Render process gone:', details.reason); // 可以在这里添加恢复逻辑 }); // 抑制Electron安全警告 mainWindow.webContents.on('console-message', (event, level, message, line, sourceId) => { // 抑制Autofill相关警告 if (message.includes('Autofill.enable failed') || message.includes('Autofill.setAddresses failed') || message.includes('Request Autofill')) { event.preventDefault(); return false; } // 抑制Electron安全警告 if (message.includes('Electron Security Warning') || message.includes('Insecure Content-Security-Policy') || message.includes('unsafe-eval')) { event.preventDefault(); return false; } }); } const loadPath = path.join(appRoot, 'dist/renderer/index.html') console.log('Loading:', loadPath) // 检查文件是否存在 if (!fs.existsSync(loadPath)) { console.log('File not found, waiting for build completion...'); // 在watch模式下等待文件构建完成 if (isDev && process.argv.includes('--watch')) { const checkFile = () => { if (fs.existsSync(loadPath)) { console.log('Build completed, starting to load...'); loadMainWindow(); } else { setTimeout(checkFile, 1000); // 每秒检查一次 } }; checkFile(); return; // 重要:如果文件不存在,直接返回,不执行后续代码 } else { // 非watch模式,直接显示错误 console.error('File not found:', loadPath); mainWindow.loadURL(`data:text/html,

Build file not found, please run npm run dev first

`); return; } } // 文件存在,直接加载 loadMainWindow(); function loadMainWindow() { mainWindow.loadFile(loadPath).then(() => { console.log('Page loaded successfully'); // 开发环境下打开开发者工具 if (isDev) { mainWindow.webContents.openDevTools() } // 页面加载完成后显示窗口 mainWindow.show() }).catch(err => { console.error('Load failed:', err) mainWindow.loadURL(`data:text/html,

Load failed: ${err.toString()}

`) // 即使加载失败也要显示窗口 mainWindow.show() }) } // 窗口关闭事件 mainWindow.on('closed', () => { mainWindow = null }) } catch (error) { console.error('Failed to create window:', error) } } app.whenReady().then(() => { console.log('Electron app ready'); // 初始化日志系统 initLogging() createWindow() // 修复IPC通信问题 ipcMain.on('request-status', (event) => { try { const statusData = { status: 'running', timestamp: Date.now() } event.sender.send('status-update', statusData) } catch (error) { console.error('IPC communication error:', error); } }) // 添加获取进程内存信息的API ipcMain.handle('get-process-memory-info', async (event) => { try { // 使用 process.memoryUsage 获取内存信息 const memoryUsage = process.memoryUsage(); // 获取更详细的系统内存信息 let systemMemoryInfo = {}; try { // 尝试使用 require('os') 获取系统内存信息 const os = require('os'); systemMemoryInfo = { totalMemory: os.totalmem(), freeMemory: os.freemem(), usedMemory: os.totalmem() - os.freemem() }; } catch (osError) { console.warn('Cannot get system memory info:', osError.message); } return { // 进程内存使用情况 privateBytes: memoryUsage.rss, // Resident Set Size - 进程占用的物理内存 sharedBytes: memoryUsage.external, // 外部内存使用 heapUsed: memoryUsage.heapUsed, // JavaScript堆内存使用 heapTotal: memoryUsage.heapTotal, // JavaScript堆内存总量 // 系统内存信息 systemTotal: systemMemoryInfo.totalMemory || 0, systemFree: systemMemoryInfo.freeMemory || 0, systemUsed: systemMemoryInfo.usedMemory || 0 }; } catch (error) { console.error('Failed to get memory info:', error); // 返回默认值 return { privateBytes: 0, sharedBytes: 0, heapUsed: 0, heapTotal: 0, systemTotal: 0, systemFree: 0, systemUsed: 0 }; } }); // 添加更新窗口标题的API ipcMain.handle('update-window-title', async (event, newTitle) => { try { if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.setTitle(newTitle); return { success: true, message: '窗口标题更新成功' }; } else { return { success: false, message: '主窗口不存在或已销毁' }; } } catch (error) { console.error('更新窗口标题失败:', error); return { success: false, message: '更新窗口标题失败: ' + error.message }; } }); // 获取错误日志计数 ipcMain.handle('get-error-log-count', async () => { return { count: errorLogCount } }); // 获取日志文件路径 ipcMain.handle('get-log-file-path', async () => { return { path: logFilePath } }); // 打开日志文件所在文件夹 ipcMain.handle('open-log-folder', async () => { try { const path = require('path'); const logDir = path.dirname(logFilePath); require('electron').shell.openPath(logDir); return { success: true, message: '日志文件夹已打开' }; } catch (error) { console.error('打开日志文件夹失败:', error); return { success: false, message: '打开日志文件夹失败: ' + error.message }; } }); // 获取本地IP地址 ipcMain.handle('get-local-ip', async () => { try { const ipInfo = getLocalIPAddresses(); if (ipInfo) { return { success: true, ip: ipInfo.address, interface: ipInfo.name, netmask: ipInfo.netmask }; } else { return { success: false, message: '无法获取本地IP地址', fallback: '127.0.0.1' }; } } catch (error) { console.error('获取本地IP地址失败:', error); return { success: false, message: '获取本地IP地址失败: ' + error.message, fallback: '127.0.0.1' }; } }); }); // 闭合 app.whenReady().then() 的回调函数 app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() }) app.on('activate', () => { if (mainWindow === null) createWindow() }) // 添加错误处理 process.on('uncaughtException', (error) => { console.error('Uncaught exception:', error) }) process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled promise rejection:', reason) }) // 测试日志系统 - 在开发环境下生成一些测试错误 if (isDev) { setTimeout(() => { console.error('测试错误日志 1: 这是一个模拟的错误信息') }, 5000) setTimeout(() => { console.error('测试错误日志 2: 另一个模拟的错误信息') }, 10000) }