112 lines
2.8 KiB
JavaScript
112 lines
2.8 KiB
JavaScript
const { app, Tray, Menu, nativeImage } = require('electron');
|
||
const path = require('path');
|
||
const fs = require('fs');
|
||
const { spawn } = require('child_process');
|
||
|
||
let tray = null;
|
||
let serverPort = '3000';
|
||
|
||
function startServer() {
|
||
console.log('Starting OpenChamber server...');
|
||
|
||
let serverPath;
|
||
let cwdPath;
|
||
let execPath;
|
||
|
||
if (app.isPackaged) {
|
||
serverPath = path.join(process.resourcesPath, 'server', 'index.js');
|
||
cwdPath = path.join(process.resourcesPath);
|
||
execPath = path.join(process.resourcesPath, 'nodejs', 'node.exe');
|
||
} else {
|
||
serverPath = path.join(__dirname, '..', 'server', 'index.js');
|
||
cwdPath = path.join(__dirname, '..');
|
||
execPath = 'node';
|
||
}
|
||
|
||
console.log('Server path:', serverPath);
|
||
console.log('CWD:', cwdPath);
|
||
console.log('Exec:', execPath);
|
||
|
||
// 支持命令行参数或环境变量指定端口
|
||
const port = process.argv.find(arg => arg.startsWith('--port='))?.split('=')[1]
|
||
|| process.env.OPENCHAMBER_PORT
|
||
|| '3000';
|
||
|
||
serverPort = port;
|
||
console.log('Port:', port);
|
||
|
||
try {
|
||
// 设置环境变量
|
||
const env = { ...process.env };
|
||
env.OPENCHAMBER_PORT = port;
|
||
env.OPENCODE_SKIP_START = 'true';
|
||
|
||
// 直接 spawn,用命令行参数指定端口
|
||
const child = spawn(execPath, [serverPath, '--port=' + port], {
|
||
cwd: cwdPath,
|
||
stdio: 'inherit',
|
||
env: env,
|
||
windowsHide: true
|
||
});
|
||
|
||
child.on('error', (err) => {
|
||
console.error('Server error:', err);
|
||
});
|
||
|
||
child.on('exit', (code) => {
|
||
console.log('Server exited:', code);
|
||
});
|
||
} catch (e) {
|
||
console.error('Failed to start:', e);
|
||
}
|
||
}
|
||
|
||
function createTray(port) {
|
||
try {
|
||
let iconPath;
|
||
if (app.isPackaged) {
|
||
iconPath = path.join(process.resourcesPath, 'public', 'favicon.png');
|
||
} else {
|
||
iconPath = path.join(__dirname, '..', 'public', 'favicon.png');
|
||
}
|
||
|
||
let icon;
|
||
try {
|
||
icon = nativeImage.createFromPath(iconPath);
|
||
if (icon.isEmpty()) {
|
||
icon = nativeImage.createEmpty();
|
||
}
|
||
} catch (e) {
|
||
icon = nativeImage.createEmpty();
|
||
}
|
||
|
||
tray = new Tray(icon);
|
||
|
||
const contextMenu = Menu.buildFromTemplate([
|
||
{ label: `OpenChamber Server (:${port})`, enabled: false },
|
||
{ type: 'separator' },
|
||
{ label: `Open http://localhost:${port}`, click: () => {
|
||
require('electron').shell.openExternal(`http://localhost:${port}`);
|
||
}},
|
||
{ type: 'separator' },
|
||
{ label: 'Quit', click: () => {
|
||
app.quit();
|
||
}}
|
||
]);
|
||
|
||
tray.setToolTip(`OpenChamber Server (:${port})`);
|
||
tray.setContextMenu(contextMenu);
|
||
} catch (e) {
|
||
console.error('Failed to create tray:', e);
|
||
}
|
||
}
|
||
|
||
app.whenReady().then(() => {
|
||
startServer();
|
||
createTray(serverPort);
|
||
});
|
||
|
||
app.on('window-all-closed', () => {
|
||
app.quit();
|
||
});
|