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 = ""; let mainWindow = null; let close_flag = 0; let ipcRegistered = false; // 1. 定义数据路径(放在全局,方便后续调用) const exePath = app.getPath('userData'); const historyFilePath = path.join(exePath, 'data.json'); console.log('User data path:', exePath); function printPDF(pdfData) { const printWindow = new BrowserWindow({ show: true }); printWindow.loadURL(pdfData); printWindow.webContents.on("did-finish-load", () => { printWindow.webContents.print({}); }); } function registerIpcHandlers() { if (ipcRegistered) return; ipcRegistered = true; 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: [] }; } }); 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(); }); ipcMain.handle('file:read-json', async (event, filePath) => { try { if (!filePath || !fs.existsSync(filePath)) return null; const data = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(data); } catch (err) { return null; } }); 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()); }); ipcMain.on("open-help-file", async (event) => { let helpPath; const fileName = 'User Manual.pdf'; if (app.isPackaged) { if (process.platform === 'linux') { const possiblePaths = [ path.join(process.resourcesPath, 'help', fileName), path.join(process.resourcesPath, 'app.asar', 'help', fileName), path.join(__dirname, 'assets', 'help', fileName), path.join(process.resourcesPath, '..', 'help', fileName) ]; for (const testPath of possiblePaths) { if (fs.existsSync(testPath)) { helpPath = testPath; break; } } } else { helpPath = path.join(process.resourcesPath, 'help', fileName); } } else { helpPath = path.join(__dirname, 'assets', 'help', fileName); } console.log("Help file path: ", helpPath); if (helpPath && fs.existsSync(helpPath)) { try { if (process.platform === 'linux') { await shell.openExternal(`file://${helpPath}`); } else { const errorMessage = await shell.openPath(helpPath); if (errorMessage) { console.error('Error opening help file:', errorMessage); await shell.openExternal(`file://${helpPath}`); } } console.log('Help file opened successfully'); } catch (err) { console.error('Exception when opening file:', err); try { await shell.openExternal(`file://${helpPath}`); } catch (err2) { console.error('Failed to open with openExternal:', err2); } } } else { console.error('Help file not found at:', helpPath); const searchPaths = [ path.join(__dirname, 'assets', 'help', fileName), path.join(app.getAppPath(), 'help', fileName) ]; for (const searchPath of searchPaths) { if (fs.existsSync(searchPath)) { console.log('Found help file at alternative path:', searchPath); try { if (process.platform === 'linux') { await shell.openExternal(`file://${searchPath}`); } else { await shell.openPath(searchPath); } return; } catch (err) { console.error('Failed to open help file:', err); } } } } }); ipcMain.on("print-pdf", (event, pdfData) => { printPDF(pdfData); }); ipcMain.on("open-design-page", (event, arg, type) => { if (!mainWindow) return; arg = arg ? arg : 'empty'; type = type ? type : '1'; mainWindow.loadURL(`file://${path.join(__dirname, "pages", "design" + type + ".html")}?file=${encodeURIComponent(arg)}&type=${type}`); }); ipcMain.on("open-first-page", (event, arg) => { if (!mainWindow) return; mainWindow.loadURL(`file://${path.join(__dirname, "pages", "index.html")}`); }); ipcMain.on("run-close", (event, arg) => { close_flag = 1; app.quit(); }); } 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() { registerIpcHandlers(); close_flag = 0; let size = require("electron").screen.getPrimaryDisplay().workAreaSize; mainWindow = new BrowserWindow({ show: false, width: size.width, height: size.height, resizable: false, icon: path.join(__dirname, "assets/images/favicon.ico"), 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://${path.join(__dirname, "pages", "design" + type + ".html")}?file=${encodeURIComponent(preFilePath)}&type=${type}`); } catch (e) { console.error("Error loading preFilePath:", e); mainWindow.loadFile(path.join(__dirname, "pages", "index.html")); } } else { mainWindow.loadFile(path.join(__dirname, "pages", "index.html")); } var closeHandler = function (e) { if (close_flag == 0) { e.preventDefault(); mainWindow.webContents.send("close"); } }; mainWindow.on("close", closeHandler); mainWindow.show(); 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(); });