Files
erp_sb/electron-vue-template/src/main/main.ts
2025-09-25 16:12:31 +08:00

183 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 主进程:创建窗口、启动后端 JAR、隐藏菜单栏
import {app, BrowserWindow, ipcMain, session, Menu, screen} from 'electron';
import { Socket } from 'net';
import { existsSync } from 'fs';
import {join, dirname} from 'path';
import {spawn, ChildProcessWithoutNullStreams} from 'child_process';
// 保存后端进程与窗口引用,便于退出时清理
let springProcess: ChildProcessWithoutNullStreams | null = null;
let mainWindow: BrowserWindow | null = null;
let splashWindow: BrowserWindow | null = null;
let appOpened = false;
function openAppIfNotOpened() {
if (appOpened) return;
appOpened = true;
if (mainWindow) {
mainWindow.show();
mainWindow.focus();
}
if (splashWindow) { splashWindow.close(); splashWindow = null; }
}
// 启动后端 Spring Boot使用你提供的绝对路径
function startSpringBoot() {
const jarPath = 'C:/Users/ZiJIe/Desktop/wox/RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar';
springProcess = spawn('java', ['-jar', jarPath], {
cwd: dirname(jarPath),
detached: false
});
// 打印后端日志,监听启动成功标志
springProcess.stdout.on('data', (data) => {
console.log(`SpringBoot: ${data}`);
// 检测到启动成功日志立即进入主界面
if (data.toString().includes('Started RuoYiApplication')) {
openAppIfNotOpened();
}
});
// 打印后端错误,检测启动失败
springProcess.stderr.on('data', (data) => {
console.error(`SpringBoot ERROR: ${data}`);
const errorStr = data.toString();
// 检测到关键错误信息,直接退出
if (errorStr.includes('APPLICATION FAILED TO START') ||
errorStr.includes('Port') && errorStr.includes('already in use') ||
errorStr.includes('Unable to start embedded Tomcat')) {
console.error('后端启动失败,程序即将退出');
app.quit();
}
});
// 后端退出时,前端同步退出
springProcess.on('close', (code) => {
console.log(`SpringBoot exited with code ${code}`);
if (mainWindow) {
mainWindow.close();
} else {
app.quit();
}
});
}
// 关闭后端进程Windows 使用 taskkill 结束整个进程树)
function stopSpringBoot() {
if (!springProcess) return;
try {
if (process.platform === 'win32') {
// Force kill the whole process tree on Windows
try {
const pid = springProcess.pid;
if (pid !== undefined && pid !== null) {
spawn('taskkill', ['/pid', String(pid), '/f', '/t']);
} else {
springProcess.kill();
}
} catch (e) {
// Fallback
springProcess.kill();
}
} else {
springProcess.kill('SIGTERM');
}
} catch (e) {
console.error('Failed to stop Spring Boot process:', e);
} finally {
springProcess = null;
}
}
function createWindow () {
mainWindow = new BrowserWindow({
width: 1280,
height: 800,
show: false,
autoHideMenuBar: true,
icon: join(__dirname, '../renderer/icon/icon.png'), // 添加窗口图标
webPreferences: {
preload: join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
}
});
// 彻底隐藏原生菜单栏
try {
Menu.setApplicationMenu(null);
mainWindow.setMenuBarVisibility(false);
if (typeof (mainWindow as any).setMenu === 'function') {
(mainWindow as any).setMenu(null);
}
} catch {}
// 生产环境加载本地文件
if (process.env.NODE_ENV === 'development') {
const rendererPort = process.argv[2] || 8083;
mainWindow.loadURL(`http://localhost:${rendererPort}`);
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
}
}
app.whenReady().then(() => {
// 预创建主窗口(隐藏)
createWindow();
// 显示启动页
const { width: sw, height: sh } = screen.getPrimaryDisplay().workAreaSize;
const splashW = Math.min(Math.floor(sw * 0.8), 1800);
const splashH = Math.min(Math.floor(sh * 0.8), 1200);
splashWindow = new BrowserWindow({
width: splashW,
height: splashH,
frame: false,
transparent: false,
resizable: false,
alwaysOnTop: true,
show: true,
center: true,
});
const candidateSplashPaths = [
join(__dirname, '../../public', 'splash.html'),
];
const foundSplash = candidateSplashPaths.find(p => existsSync(p));
if (foundSplash) {
splashWindow.loadFile(foundSplash);
}
// 注释掉后端启动,便于快速调试前端
// startSpringBoot();
// 快速调试模式 - 直接打开主窗口
setTimeout(() => {
openAppIfNotOpened();
}, 1000);
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', function () {
stopSpringBoot();
if (process.platform !== 'darwin') app.quit()
});
app.on('before-quit', () => {
stopSpringBoot();
});
ipcMain.on('message', (event, message) => {
console.log(message);
})