This commit is contained in:
24kycj
2025-11-15 15:41:54 +08:00
parent 6a4a448cfd
commit 01c8b05d30
5 changed files with 288 additions and 219 deletions
+2 -1
View File
@@ -26,7 +26,8 @@
"output": "build" "output": "build"
}, },
"extraFiles": [ "extraFiles": [
"lib" "lib",
"ProductionServer"
], ],
"nsis": { "nsis": {
"oneClick": false, "oneClick": false,
+278 -210
View File
@@ -1,210 +1,278 @@
const { Menu, app, BrowserWindow } = require("electron"); const { Menu, app, BrowserWindow, shell } = require("electron");
// Note: Store should be handled in renderer process, not main // Note: Store should be handled in renderer process, not main
// import "../renderer/store"; // import "../renderer/store";
const fs = require('fs'); const fs = require('fs');
const child_process = require('child_process'); const child_process = require('child_process');
const path = require('path') const path = require('path')
// 导入录制器模块(设置全局变量) // 导入录制器模块(设置全局变量)
require('./recorder'); require('./recorder');
// require("./fingerprint/win"); // require("./fingerprint/win");
let root = ""; // 获取应用根目录(兼容三端,与 exe 同级)
if (process.env.NODE_ENV !== "development") { // 开发环境:使用项目根目录
root = path.dirname(app.getPath("exe")); // 生产环境:获取可执行文件所在目录(与 exe 同级,兼容 Windows/Linux/macOS
} else { let root = "";
root = "..\\..\\"; if (process.env.NODE_ENV === "development") {
} root = path.join(__dirname, '../../');
} else {
// 获取日志文件的路径 root = path.dirname(app.getPath("exe"));
const logPath = path.join(app.getPath('userData'), 'app.log'); }
// 写入日志的函数
function writeLog(message) { // 获取日志文件的路径
const timestamp = new Date().toISOString(); const logPath = path.join(app.getPath('userData'), 'app.log');
const logMessage = `${timestamp}: ${message}\n`; // 写入日志的函数
// 异步追加日志信息 function writeLog(message) {
fs.appendFile(logPath, logMessage, (err) => { const timestamp = new Date().toISOString();
if (err) throw err; const logMessage = `${timestamp}: ${message}\n`;
console.log('日志信息已追加到文件'); // 异步追加日志信息
}); fs.appendFile(logPath, logMessage, (err) => {
} if (err) throw err;
console.log('日志信息已追加到文件');
});
/** }
* Set `__static` path to static files in production
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
*/ /**
if (process.env.NODE_ENV !== "development") { * Set `__static` path to static files in production
global.__static = require("path") * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
.join(__dirname, "/static") */
.replace(/\\/g, "\\\\"); if (process.env.NODE_ENV !== "development") {
} global.__static = require("path")
.join(__dirname, "/static")
let mainWindow; .replace(/\\/g, "\\\\");
const winURL = }
process.env.NODE_ENV === "development"
? `http://localhost:9081` let mainWindow;
: `file://${__dirname}/index.html`; const winURL =
process.env.NODE_ENV === "development"
function createWindow() { ? `http://localhost:9081`
/** : `file://${__dirname}/index.html`;
* Initial window options
*/ function createWindow() {
mainWindow = new BrowserWindow({ /**
height: 800, * Initial window options
useContentSize: true, */
width: 1280, mainWindow = new BrowserWindow({
title: "卡树自动拷贝打印系统 V3.1", height: 800,
icon: "static/images/logo64.ico", // sets window icon useContentSize: true,
webPreferences: { width: 1280,
nodeIntegration: true, title: "卡树自动拷贝打印系统 V3.1",
contextIsolation: false, icon: "static/images/logo64.ico", // sets window icon
enableRemoteModule: true, webPreferences: {
webSecurity: false, nodeIntegration: true,
}, contextIsolation: false,
}); enableRemoteModule: true,
// mainWindow.maximize(); webSecurity: false,
// 使窗口可以拖拽 },
mainWindow.setIgnoreMouseEvents(false); });
Menu.setApplicationMenu(null); //关闭菜单 // mainWindow.maximize();
//mainWindow.webContents.openDevTools({mode:'bottom'}); // 使窗口可以拖拽
require("@electron/remote/main").initialize(); mainWindow.setIgnoreMouseEvents(false);
require("@electron/remote/main").enable(mainWindow.webContents); Menu.setApplicationMenu(null); //关闭菜单
global.setMainWindow(mainWindow); //mainWindow.webContents.openDevTools({mode:'bottom'});
mainWindow.loadURL(winURL); require("@electron/remote/main").initialize();
require("@electron/remote/main").enable(mainWindow.webContents);
mainWindow.on("closed", () => { global.setMainWindow(mainWindow);
mainWindow = null; mainWindow.loadURL(winURL);
});
} mainWindow.on("closed", () => {
app.commandLine.appendSwitch("no-sandbox"); mainWindow = null;
const gotTheLock = app.requestSingleInstanceLock(); });
if (!gotTheLock) { }
app.quit(); app.commandLine.appendSwitch("no-sandbox");
} else { const gotTheLock = app.requestSingleInstanceLock();
app.on("second-instance", (event, commandLine, workingDirectory) => { if (!gotTheLock) {
// 当运行第二个实例时,将会聚焦到myWindow这个窗口 app.quit();
if (mainWindow) { } else {
if (mainWindow.isMinimized()) mainWindow.restore(); app.on("second-instance", (event, commandLine, workingDirectory) => {
mainWindow.focus(); // 当运行第二个实例时,将会聚焦到myWindow这个窗口
} if (mainWindow) {
}); if (mainWindow.isMinimized()) mainWindow.restore();
} mainWindow.focus();
app.on("ready", createWindow); }
});
app.on("window-all-closed", () => { }
if (process.platform !== "darwin") { // 执行安装脚本(仅在首次安装时执行一次,兼容三端,无需额外权限)
app.quit(); function runInstallScript() {
} const productionServerPath = path.join(root, "ProductionServer");
}); const installFlagPath = path.join(productionServerPath, ".install_completed");
app.on("activate", () => { // 检查是否已执行过
if (mainWindow === null) { if (fs.existsSync(installFlagPath)) {
createWindow(); console.log("安装脚本已执行过,跳过本次执行");
} return;
}); }
app.on("renderer-process-crashed", function (event, webContents, details) {
// 输出一下捕捉到的reason,实际可以根据不同的“原因”进行具体处理 // 根据平台确定脚本文件名和命令(使用 sh 执行 .sh 文件无需执行权限)
console.error("renderer-process-crashed, reason => ", JSON.stringify(details)); const scriptName = process.platform === "win32" ? "install.bat" : "install.sh";
// 重启应用 const installScriptPath = path.join(productionServerPath, scriptName);
writeLog("renderer-process-crashed, reason => " + JSON.stringify(details)) const execCommand = process.platform === "win32"
}); ? `"${installScriptPath}"`
: `sh "${installScriptPath}"`; // 使用 sh 执行,无需执行权限
const { ipcMain } = require("electron");
let preFilePath = ""; // 检查脚本是否存在
// app.on("will-finish-launching", () => { if (!fs.existsSync(installScriptPath)) {
app.on("open-file", (e, filePath) => { console.log("安装脚本不存在: " + installScriptPath);
preFilePath = filePath; return;
}); }
ipcMain.on('open-help-file', event => { // 执行安装脚本
var exePath = path.dirname(app.getPath('exe')); console.log("首次安装,执行安装脚本: " + installScriptPath);
child_process.exec(`start "" "${exePath}/help/User Manual.pdf"`); writeLog(`首次安装,执行安装脚本: ${installScriptPath} (平台: ${process.platform})`);
});
child_process.exec(execCommand, { cwd: productionServerPath }, (error, stdout, stderr) => {
ipcMain.on("get-root", (event) => { if (error) {
event.reply("get-root-callback", root); console.error("安装脚本执行错误:", error);
}); writeLog("安装脚本执行错误: " + error.message);
return;
if (process.platform === "win32" && process.argv.length >= 2) { }
console.log("process argv:", process.argv);
// windows系统当没有路径参数时这个位置默认有个.,需要加以判断 // 执行成功,创建标记文件
preFilePath = process.argv[1] === "." ? "" : process.argv[1]; try {
} fs.writeFileSync(installFlagPath, new Date().toISOString(), "utf-8");
// }); console.log("安装脚本执行完成");
writeLog("安装脚本执行完成");
ipcMain.on("open-program", (event) => { if (stdout) console.log("输出:", stdout);
if (process.env.NODE_ENV !== "development") { if (stderr) console.error("错误输出:", stderr);
//调试模式下不运行此行 } catch (writeErr) {
if (preFilePath != "") { console.error("创建安装标记文件失败:", writeErr);
event.reply("open-program-callback", preFilePath); writeLog("创建安装标记文件失败: " + writeErr.message);
} }
} });
}); }
// 1. preFilePath app.on("ready", () => {
// // 在创建窗口后执行安装脚本
createWindow();
// const ffi = require('ffi-napi'); // 延迟执行安装脚本,确保应用已启动
// const { ipcMain } = require("electron"); setTimeout(() => {
// ipcMain.on("init-frp", (event) => { runInstallScript();
// let result1 = frp_cap.LIVESCAN_Init(); }, 1000);
// let result2 = frp_cap.LIVESCAN_GetChannelCount(); });
// event.reply("init-frp-callback", result1 == 1 && result2 > 0);
app.on("window-all-closed", () => {
// }); if (process.platform !== "darwin") {
app.quit();
// const frp = new ffi.Library('../../lib/ID_FprCap.dll', { }
// 'LIVESCAN_Init': });
// [
// 'int', [], app.on("activate", () => {
// ], if (mainWindow === null) {
// 'LIVESCAN_BeginCapture': createWindow();
// [ }
// 'int', ['int'] });
// ] app.on("renderer-process-crashed", function (event, webContents, details) {
// }); // 输出一下捕捉到的reason,实际可以根据不同的“原因”进行具体处理
// let result = frp_cap.LIVESCAN_Init();//初始化 console.error("renderer-process-crashed, reason => ", JSON.stringify(details));
// console.log(`LIVESCAN_Init: ` + result); // 重启应用
writeLog("renderer-process-crashed, reason => " + JSON.stringify(details))
// result = frp_cap.LIVESCAN_GetChannelCount();//获得采集器通道数量 });
// console.log(`LIVESCAN_GetChannelCount: ` + result);
const { ipcMain } = require("electron");
// result = frp_cap.LIVESCAN_BeginCapture(0);// 准备采集一帧图像 let preFilePath = "";
// console.log(`LIVESCAN_BeginCapture: ` + result); // app.on("will-finish-launching", () => {
app.on("open-file", (e, filePath) => {
// const buf = new Buffer.alloc(256 * 360 + 1078); preFilePath = filePath;
// console.log("BMP图像获取状态:", frp_cap.LIVESCAN_GetFPBmpData(0, buf)) });
// //console.log(buf.toString('hex'))
// fs.writeFile('./1.bmp',buf,'',()=>{});//11 ipcMain.on('open-help-file', async event => {
// const buf2 = new Buffer.alloc(256 * 360); const helpFilePath = path.join(root, "ProductionServer", "User Manual.pdf");
// console.log("图像获取状态:", frp_cap.LIVESCAN_GetFPRawData(0, buf2))
// console.log(buf2.toString('hex')) try {
await shell.openPath(helpFilePath);
//console.log("buf", buf.toString("base64")); //12 } catch (error) {
//console.log("test", frp_cap.LIVESCAN_GetFPRawData(0, buf)); console.error("打开帮助文件错误:", error);
//console.log("buf", buf.toString("base64")); // writeLog("打开帮助文件错误: " + error.message);
//frp_cap.LIVESCAN_EndCapture(0); if (event.reply) {
//result = frp.FP_Begin(); event.reply('open-help-file-error', error.message);
//console.log(`FP_Begin`, result); }
// }
//const buf2 = new Buffer(512); });
//frp.FP_FeatureExtract(65, 99, buf, buf2);
//console.log("buf2: ", buf2.toString("base64")); //111111 ipcMain.on("get-root", (event) => {
/** event.reply("get-root-callback", root);
* Auto Updater });
*
* Uncomment the following code below and install `electron-updater` to if (process.platform === "win32" && process.argv.length >= 2) {
* support auto updating. Code Signing with a valid certificate is required. console.log("process argv:", process.argv);
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating // windows系统当没有路径参数时这个位置默认有个.,需要加以判断
*/ preFilePath = process.argv[1] === "." ? "" : process.argv[1];
}
/* // });
import { autoUpdater } from 'electron-updater'
ipcMain.on("open-program", (event) => {
autoUpdater.on('update-downloaded', () => { if (process.env.NODE_ENV !== "development") {
autoUpdater.quitAndInstall() //调试模式下不运行此行
}) if (preFilePath != "") {
event.reply("open-program-callback", preFilePath);
app.on('ready', () => { }
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates() }
}) });
*/
// 1. preFilePath
//
// const ffi = require('ffi-napi');
// const { ipcMain } = require("electron");
// ipcMain.on("init-frp", (event) => {
// let result1 = frp_cap.LIVESCAN_Init();
// let result2 = frp_cap.LIVESCAN_GetChannelCount();
// event.reply("init-frp-callback", result1 == 1 && result2 > 0);
// });
// const frp = new ffi.Library('../../lib/ID_FprCap.dll', {
// 'LIVESCAN_Init':
// [
// 'int', [],
// ],
// 'LIVESCAN_BeginCapture':
// [
// 'int', ['int']
// ]
// });
// let result = frp_cap.LIVESCAN_Init();//初始化
// console.log(`LIVESCAN_Init: ` + result);
// result = frp_cap.LIVESCAN_GetChannelCount();//获得采集器通道数量
// console.log(`LIVESCAN_GetChannelCount: ` + result);
// result = frp_cap.LIVESCAN_BeginCapture(0);// 准备采集一帧图像
// console.log(`LIVESCAN_BeginCapture: ` + result);
// const buf = new Buffer.alloc(256 * 360 + 1078);
// console.log("BMP图像获取状态:", frp_cap.LIVESCAN_GetFPBmpData(0, buf))
// //console.log(buf.toString('hex'))
// fs.writeFile('./1.bmp',buf,'',()=>{});//11
// const buf2 = new Buffer.alloc(256 * 360);
// console.log("图像获取状态:", frp_cap.LIVESCAN_GetFPRawData(0, buf2))
// console.log(buf2.toString('hex'))
//console.log("buf", buf.toString("base64")); //12
//console.log("test", frp_cap.LIVESCAN_GetFPRawData(0, buf));
//console.log("buf", buf.toString("base64")); //
//frp_cap.LIVESCAN_EndCapture(0);
//result = frp.FP_Begin();
//console.log(`FP_Begin`, result);
//
//const buf2 = new Buffer(512);
//frp.FP_FeatureExtract(65, 99, buf, buf2);
//console.log("buf2: ", buf2.toString("base64")); //111111
/**
* Auto Updater
*
* Uncomment the following code below and install `electron-updater` to
* support auto updating. Code Signing with a valid certificate is required.
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
*/
/*
import { autoUpdater } from 'electron-updater'
autoUpdater.on('update-downloaded', () => {
autoUpdater.quitAndInstall()
})
app.on('ready', () => {
if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
})
*/
+2 -2
View File
@@ -167,7 +167,7 @@ export default {
//fs.writeFileSync("../Debug/config.ini"); //fs.writeFileSync("../Debug/config.ini");
let that = this; let that = this;
fs.writeFile( fs.writeFile(
this.root + "/../ProductionServer/config.ini", this.root + "/ProductionServer/config.ini",
ini.stringify(this.iniData), ini.stringify(this.iniData),
function (err) { function (err) {
if (err) { if (err) {
@@ -187,7 +187,7 @@ export default {
//var data = ini.parse(fs.readFileSync("F:\\controll\\config.ini", "utf-8")); //var data = ini.parse(fs.readFileSync("F:\\controll\\config.ini", "utf-8"));
ipcRenderer.on("get-root-callback", (event, data) => { ipcRenderer.on("get-root-callback", (event, data) => {
this.root = data; this.root = data;
fs.readFile(this.root + "/../ProductionServer/config.ini", "utf-8", (err, res) => { fs.readFile(this.root + "/ProductionServer/config.ini", "utf-8", (err, res) => {
if (err) { if (err) {
console.log(err); console.log(err);
this.$message.error(that.$t("dispose.errorRead")); this.$message.error(that.$t("dispose.errorRead"));
+3 -3
View File
@@ -1276,9 +1276,9 @@ export default {
}, },
getOS() { getOS() {
let that = this let that = this
console.log(this.root + '/../ProductionServer/config.ini') console.log(this.root + '/ProductionServer/config.ini')
fs.readFile(this.root + '/../ProductionServer/config.ini', 'utf-8', (err, res) => { fs.readFile(this.root + '/ProductionServer/config.ini', 'utf-8', (err, res) => {
console.log(this.root + '/../ProductionServer/config.ini') console.log(this.root + '/ProductionServer/config.ini')
if (err) { if (err) {
that.isLocal = false that.isLocal = false
} else { } else {
+3 -3
View File
@@ -1296,9 +1296,9 @@ export default {
}, },
getOS() { getOS() {
let that = this let that = this
console.log(this.root + '/../ProductionServer/config.ini') console.log(this.root + '/ProductionServer/config.ini')
fs.readFile(this.root + '/../ProductionServer/config.ini', 'utf-8', (err, res) => { fs.readFile(this.root + '/ProductionServer/config.ini', 'utf-8', (err, res) => {
console.log(this.root + '/../ProductionServer/config.ini') console.log(this.root + '/ProductionServer/config.ini')
if (err) { if (err) {
that.isLocal = false that.isLocal = false
} else { } else {