绿色包,mysql处理成即用即启,而非服务的形式,因为注册服务需要管理员身份
This commit is contained in:
@@ -67,7 +67,6 @@ class Lifecycle {
|
||||
this.mysqlPort = null;
|
||||
this.javaPort = null;
|
||||
this.autoRefreshTimer = null;
|
||||
this.isRestartingForAdmin = false; // 权限提升重启标记
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,23 +118,8 @@ class Lifecycle {
|
||||
this.startupManager.updateProgress('wait-mysql', { mysqlPort: this.mysqlPort });
|
||||
await this.sleep(500);
|
||||
} catch (error) {
|
||||
logger.error('[lifecycle] MySQL service error:', error);
|
||||
this.logWindowManager.addLog('error', `MySQL 服务错误: ${error.message}`);
|
||||
// 检查是否是权限问题
|
||||
if (error.message && (error.message.includes('administrator') || error.message.includes('Denied'))) {
|
||||
logger.error('[lifecycle] Need administrator privileges');
|
||||
this.logWindowManager.addLog('error', '检测到需要管理员权限来安装 MySQL 服务');
|
||||
this.logWindowManager.addLog('system', '应用将自动请求管理员权限并重启...');
|
||||
|
||||
// 等待用户看清日志
|
||||
await this.sleep(2000);
|
||||
|
||||
// 自动以管理员身份重启应用
|
||||
await this.restartAsAdmin();
|
||||
|
||||
// 退出当前实例
|
||||
return;
|
||||
}
|
||||
logger.error('[lifecycle] MySQL error:', error);
|
||||
this.logWindowManager.addLog('error', `MySQL 错误: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -350,12 +334,6 @@ class Lifecycle {
|
||||
async cleanup() {
|
||||
logger.info('[lifecycle] Starting cleanup...');
|
||||
|
||||
// 如果是权限提升重启,跳过清理(服务需要继续运行)
|
||||
if (this.isRestartingForAdmin) {
|
||||
logger.info('[lifecycle] Restarting for admin, skip cleanup');
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除自动刷新定时器
|
||||
if (this.autoRefreshTimer) {
|
||||
clearTimeout(this.autoRefreshTimer);
|
||||
@@ -397,10 +375,26 @@ class Lifecycle {
|
||||
}
|
||||
}
|
||||
|
||||
// MySQL 作为Windows服务运行,应用关闭时保持运行
|
||||
logger.info('[lifecycle] MySQL service keeps running as Windows service');
|
||||
// 停止 MySQL 进程(进程模式)
|
||||
if (this.mysqlServiceManager) {
|
||||
try {
|
||||
logger.info('[lifecycle] Stopping MySQL process...');
|
||||
if (this.logWindowManager && this.logWindowManager.logWindow && !this.logWindowManager.logWindow.isDestroyed()) {
|
||||
this.logWindowManager.addLog('system', '正在停止 MySQL...');
|
||||
}
|
||||
|
||||
await this.mysqlServiceManager.stopMySQLProcess();
|
||||
|
||||
logger.info('[lifecycle] MySQL process stopped');
|
||||
if (this.logWindowManager && this.logWindowManager.logWindow && !this.logWindowManager.logWindow.isDestroyed()) {
|
||||
this.logWindowManager.addLog('success', 'MySQL 已停止');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('[lifecycle] Failed to stop MySQL:', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.logWindowManager && this.logWindowManager.logWindow && !this.logWindowManager.logWindow.isDestroyed()) {
|
||||
this.logWindowManager.addLog('system', 'MySQL 服务保持运行');
|
||||
this.logWindowManager.addLog('system', '清理完成,应用即将退出');
|
||||
this.logWindowManager.addLog('system', '='.repeat(60));
|
||||
}
|
||||
@@ -485,72 +479,6 @@ class Lifecycle {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 以管理员身份重启应用
|
||||
*/
|
||||
async restartAsAdmin() {
|
||||
const { app, dialog } = require('electron');
|
||||
const { spawn } = require('child_process');
|
||||
const path = require('path');
|
||||
|
||||
logger.info('[lifecycle] Requesting administrator privileges...');
|
||||
|
||||
try {
|
||||
// 显示提示对话框
|
||||
await dialog.showMessageBox({
|
||||
type: 'warning',
|
||||
title: '告警',
|
||||
message: '需要管理员权限',
|
||||
buttons: ['确定']
|
||||
});
|
||||
|
||||
// 用户点击确定,以管理员身份重启
|
||||
|
||||
// 获取应用可执行文件路径
|
||||
const exePath = app.getPath('exe');
|
||||
logger.info('[lifecycle] Restarting with admin privileges:', exePath);
|
||||
|
||||
// 使用 PowerShell 以管理员身份启动
|
||||
const psCommand = `Start-Process -FilePath "${exePath}" -Verb RunAs`;
|
||||
|
||||
const child = spawn('powershell.exe', ['-Command', psCommand], {
|
||||
detached: true,
|
||||
stdio: 'ignore',
|
||||
windowsHide: true
|
||||
});
|
||||
|
||||
// 分离子进程,父进程退出不影响子进程
|
||||
child.unref();
|
||||
|
||||
// 立即退出当前实例,释放单实例锁
|
||||
// 必须立即退出,否则新实例会因为单实例锁无法启动
|
||||
logger.info('[lifecycle] Quitting current instance to release lock...');
|
||||
|
||||
// 设置标记,跳过清理流程(这只是重启,不是真正退出)
|
||||
this.isRestartingForAdmin = true;
|
||||
|
||||
// 关闭所有窗口
|
||||
const BrowserWindow = require('electron').BrowserWindow;
|
||||
BrowserWindow.getAllWindows().forEach(win => {
|
||||
try {
|
||||
win.destroy();
|
||||
} catch (e) {
|
||||
// 忽略错误
|
||||
}
|
||||
});
|
||||
|
||||
// 立即强制退出,释放锁
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
logger.error('[lifecycle] Failed to restart as admin:', error);
|
||||
this.logWindowManager.addLog('error', '自动提升权限失败,请手动以管理员身份运行');
|
||||
|
||||
// 等待5秒后关闭
|
||||
await this.sleep(5000);
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 睡眠函数
|
||||
*/
|
||||
@@ -558,24 +486,6 @@ class Lifecycle {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有管理员权限(仅 Windows)
|
||||
*/
|
||||
checkAdminPrivileges() {
|
||||
if (process.platform !== 'win32') {
|
||||
return true; // 非 Windows 系统不需要检查
|
||||
}
|
||||
|
||||
try {
|
||||
const { execSync } = require('child_process');
|
||||
// 尝试执行需要管理员权限的命令
|
||||
execSync('net session', { stdio: 'ignore' });
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* electron app ready
|
||||
*/
|
||||
@@ -589,16 +499,7 @@ class Lifecycle {
|
||||
async windowReady() {
|
||||
logger.info('[lifecycle] window-ready hook triggered');
|
||||
|
||||
// 在创建任何窗口之前,先检查管理员权限
|
||||
const hasAdminPrivileges = this.checkAdminPrivileges();
|
||||
logger.info('[lifecycle] Has admin privileges:', hasAdminPrivileges);
|
||||
|
||||
if (!hasAdminPrivileges) {
|
||||
logger.warn('[lifecycle] No admin privileges, requesting elevation');
|
||||
// 调用已有的 restartAsAdmin 方法,避免代码重复
|
||||
await this.restartAsAdmin();
|
||||
return; // 阻止后续代码执行
|
||||
}
|
||||
// 进程模式不需要管理员权限检查
|
||||
|
||||
// 创建日志管理器(但不显示窗口,仅用于写日志文件)
|
||||
logger.info('[lifecycle] Creating log window manager...');
|
||||
|
||||
Reference in New Issue
Block a user