import { app, BrowserWindow, ipcMain } from "electron"; import path from "node:path"; import started from "electron-squirrel-startup"; import { logger } from '@modules/logger' import "@modules/window-size"; if (started) { app.quit(); } class AppMain { private mainWindow: BrowserWindow | null = null private readonly isDev = !!MAIN_WINDOW_VITE_DEV_SERVER_URL init() { this.registerLifecycle() this.registerAppIPC() // this.registerLogIPC() } private createWindow(options?: { frameless?: boolean; route?: string }): BrowserWindow { const frameless = !!options?.frameless const win = new BrowserWindow({ width: 1440, height: 900, autoHideMenuBar: true, frame: frameless ? false : true, // @ts-ignore windowButtonVisibility: frameless ? false : true, resizable: true, maximizable: true, minimizable: true, titleBarStyle: 'hidden', title: 'NIANXX', webPreferences: { devTools: this.isDev, nodeIntegration: false, contextIsolation: true, // 同时启动上下文隔离 sandbox: true, // 启动沙箱模式 preload: path.join(__dirname, "preload.js"), }, }) this.loadEntry(win, options?.route) if (this.isDev) win.webContents.openDevTools() this.mainWindow = win return win } private loadEntry(win: BrowserWindow, route?: string) { // @ts-ignore if (MAIN_WINDOW_VITE_DEV_SERVER_URL) { const target = route ? `${MAIN_WINDOW_VITE_DEV_SERVER_URL}${route}` : MAIN_WINDOW_VITE_DEV_SERVER_URL win.loadURL(target) } else { win.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)) } // 暴露安全 API 示例:通过 IPC 处理文件读取 ipcMain.handle('read-file', async (event, filePath) => { const fs = require('fs'); return fs.promises.readFile(filePath, 'utf-8'); // 主进程处理敏感操作 }); } private registerLifecycle() { app.on("ready", () => { this.createWindow({ frameless: false, route: '/login' }) }) app.on("window-all-closed", () => { if (process.platform !== "darwin") app.quit() }) app.on("activate", () => { if (!BrowserWindow.getAllWindows().length) this.createWindow({ frameless: false, route: '/login' }) }) } private registerAppIPC() { ipcMain.handle('app:set-frameless', async (event, route?: string) => { const old = BrowserWindow.fromWebContents(event.sender) const win = this.createWindow({ frameless: true, route }) if (old && !old.isDestroyed()) old.close() return true }) } private registerLogIPC() { ipcMain.handle('log-to-main', (_e, logLevel: string, message: string) => { switch(logLevel) { case 'trace': logger.trace(message) break case 'debug': logger.debug(message) break case 'info': logger.info(message) break case 'warn': logger.warn(message) break case 'error': logger.error(message) break default: logger.info(message) break } }) } } new AppMain().init()