const { ipcMain, Menu, shell, app, BrowserWindow, dialog } = require("electron"); const fs = require('fs'); const fontList = require("font-list"); const path = require("path"); const child_process = require("child_process"); console.log(`Node.js: ${process.versions.node}`); // 初始化 Remote 模块 require("@electron/remote/main").initialize(); let preFilePath = ""; // 1. 定义数据路径(放在全局,方便后续调用) const exePath = app.getPath('userData'); const historyFilePath = path.join(exePath, 'data.json'); console.log('User data path:', exePath); app.on("will-finish-launching", () => { app.on("open-file", (e, filePath) => { preFilePath = filePath; }); if (process.platform === "win32" && process.argv.length >= 2) { console.log("process argv:", process.argv); // windows系统当没有路径参数时这个位置默认有个.,需要加以判断 preFilePath = process.argv[1] === "." ? "" : process.argv[1]; } }); function createWindow() { // Create the browser window. let size = require("electron").screen.getPrimaryDisplay().workAreaSize; let width = parseInt(size.width); var mainWindow; mainWindow = new BrowserWindow({ show: false, width: size.width, height: size.height, resizable: false, icon: "public/images/favicon.ico", // sets window icon webPreferences: { preload: path.join(__dirname, "preload.js"), // 确保你有这个文件 nodeIntegration: true, contextIsolation: false, // 注意:为了安全建议后续开启,但目前保持你的配置 enableRemoteModule: true, }, }); mainWindow.maximize(); //Menu.setApplicationMenu(null); // 关闭菜单 // 启动逻辑:如果有预打开的文件,直接跳转 if (preFilePath) { try { let soonData = fs.readFileSync(preFilePath) let j = JSON.parse(soonData.toString()); let type = j.soonType ? j.soonType : j.backBlackPic ? 2 : 1; mainWindow.loadURL(`file://${__dirname}/design${type}.html?file=${preFilePath}&type=${type}`); } catch (e) { console.error("Error loading preFilePath:", e); mainWindow.loadFile("index.html"); } } else { mainWindow.loadFile("index.html"); } var close_flag = 0; mainWindow.on("close", function (e) { if (close_flag == 0) { e.preventDefault(); mainWindow.webContents.send("close"); } }); mainWindow.show(); // ========================================== // 新增:安全的文件读写处理 (IPC Handle) // ========================================== // 1. 读取历史记录 ipcMain.handle('history:read', async () => { try { if (!fs.existsSync(historyFilePath)) { return { history: [] }; } const data = fs.readFileSync(historyFilePath, 'utf-8'); return JSON.parse(data); } catch (err) { console.error('主进程读取历史失败:', err); return { history: [] }; } }); // 2. 写入历史记录 (包含权限检查) ipcMain.handle('history:write', async (event, data) => { try { // 简单的权限检查 if (fs.existsSync(historyFilePath)) { try { fs.accessSync(historyFilePath, fs.constants.R_OK | fs.constants.W_OK); } catch (e) { console.error("无权限写入配置文件"); return { success: false, error: "PERMISSION_DENIED" }; } } fs.writeFileSync(historyFilePath, JSON.stringify(data)); return { success: true }; } catch (err) { console.error('主进程写入历史失败:', err); return { success: false, error: err.message }; } }); // 新增:获取软件版本号 ipcMain.handle('app:get-version', () => { return app.getVersion(); // 自动读取 package.json 中的 version 字段 }); // 3. 读取 .soon 项目文件 (用于获取缩略图等) ipcMain.handle('file:read-json', async (event, filePath) => { try { if (!fs.existsSync(filePath)) return null; const data = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(data); } catch (err) { // console.error('读取文件失败:', filePath, err); return null; } }); // ========================================== // 原有的 IPC 监听 // ========================================== ipcMain.on("get-sys-fonts", (event) => { fontList.getFonts() .then((fonts) => { event.reply("font-list", fonts); }) .catch((err) => { console.log(err); }); }); ipcMain.on("get-sys-language", (event) => { event.reply("sys-lan", app.getLocale()); }); // 修复后的 Help 文件打开逻辑 ipcMain.on("open-help-file", async (event) => { let helpPath; const fileName = 'User Manual.pdf'; if (app.isPackaged) { helpPath = path.join(process.resourcesPath, 'help', fileName); } else { helpPath = path.join(process.cwd(), 'help', fileName); } console.log("Help file path: ", helpPath); if (fs.existsSync(helpPath)) { try { const errorMessage = await shell.openPath(helpPath); if (errorMessage) { console.error('Error opening help file:', errorMessage); } else { console.log('Help file opened successfully'); } } catch (err) { console.error('Exception when opening file:', err); } } else { console.error('Help file not found at:', helpPath); } }); ipcMain.on("print-pdf", (event, pdfData) => { printPDF(pdfData); }); function printPDF(pdfData) { const printWindow = new BrowserWindow({ show: true }); // 如果不想显示窗口,改 show: false printWindow.loadURL(pdfData); printWindow.webContents.on("did-finish-load", () => { printWindow.webContents.print({}); // printWindow.close(); // 打印通常是异步的,直接关闭可能导致打印失败 }); } ipcMain.on("open-design-page", (event, arg, type) => { arg = arg ? arg : 'empty' type = type ? type : '1' mainWindow.loadURL(`file://${__dirname}/design${type}.html?file=${arg}&type=${type}`); }); ipcMain.on("open-first-page", (event, arg) => { mainWindow.loadURL(`file://${__dirname}/index.html`); }); ipcMain.on("run-close", (event, arg) => { close_flag = 1; app.quit(); }); require("@electron/remote/main").enable(mainWindow.webContents); } app.commandLine.appendSwitch("no-sandbox"); app.whenReady().then(() => { createWindow(); // initialize 已经在顶部调用过,这里不需要重复调用,但保留也无害 // require("@electron/remote/main").initialize(); app.on("activate", function () { if (BrowserWindow.getAllWindows().length === 0) createWindow(); }); }); app.on("window-all-closed", function () { if (process.platform !== "darwin") app.quit(); });