fix: use spawn with ELECTRON_RUN_AS_NODE for packaged server
- Replace fork() with spawn() + ELECTRON_RUN_AS_NODE=1 so the standalone server runs correctly inside the packaged app - Set cwd to standalone directory for proper dependency resolution - Show error dialog on startup failure instead of silent quit - Add Chinese README (README_CN.md) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
337eebb53c
commit
2f40bd2c62
1 file changed
+25
-8
+25
-8
@@ -1,10 +1,11 @@
|
||||
import { app, BrowserWindow, nativeImage } from 'electron';
|
||||
import { app, BrowserWindow, nativeImage, dialog } from 'electron';
|
||||
import path from 'path';
|
||||
import { fork, ChildProcess } from 'child_process';
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import net from 'net';
|
||||
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
let serverProcess: ChildProcess | null = null;
|
||||
let serverPort: number | null = null;
|
||||
|
||||
const isDev = !app.isPackaged;
|
||||
|
||||
@@ -51,14 +52,20 @@ async function waitForServer(port: number, timeout = 30000): Promise<void> {
|
||||
function startServer(port: number): ChildProcess {
|
||||
const serverPath = path.join(process.resourcesPath, 'standalone', 'server.js');
|
||||
|
||||
const child = fork(serverPath, [], {
|
||||
// Use the bundled Node.js from Electron's helper
|
||||
const nodePath = process.execPath;
|
||||
|
||||
const child = spawn(nodePath, [serverPath], {
|
||||
env: {
|
||||
...process.env,
|
||||
PORT: String(port),
|
||||
HOSTNAME: '127.0.0.1',
|
||||
CLAUDE_GUI_DATA_DIR: app.getPath('userData'),
|
||||
// Tell Electron's Node not to load the Electron module
|
||||
ELECTRON_RUN_AS_NODE: '1',
|
||||
},
|
||||
stdio: 'pipe',
|
||||
cwd: path.join(process.resourcesPath, 'standalone'),
|
||||
});
|
||||
|
||||
child.stdout?.on('data', (data: Buffer) => {
|
||||
@@ -131,9 +138,14 @@ app.whenReady().then(async () => {
|
||||
console.log('Server is ready');
|
||||
}
|
||||
|
||||
serverPort = port;
|
||||
createWindow(port);
|
||||
} catch (err) {
|
||||
console.error('Failed to start:', err);
|
||||
dialog.showErrorBox(
|
||||
'CodePilot - Failed to Start',
|
||||
`The internal server could not start.\n\n${err instanceof Error ? err.message : String(err)}\n\nPlease try restarting the application.`
|
||||
);
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
@@ -150,12 +162,17 @@ app.on('window-all-closed', () => {
|
||||
|
||||
app.on('activate', async () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
const port = isDev ? 3000 : await getPort();
|
||||
if (!isDev && !serverProcess) {
|
||||
serverProcess = startServer(port);
|
||||
await waitForServer(port);
|
||||
try {
|
||||
if (!isDev && !serverProcess) {
|
||||
const port = await getPort();
|
||||
serverProcess = startServer(port);
|
||||
await waitForServer(port);
|
||||
serverPort = port;
|
||||
}
|
||||
createWindow(serverPort || 3000);
|
||||
} catch (err) {
|
||||
console.error('Failed to restart server:', err);
|
||||
}
|
||||
createWindow(port);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user