fix: 修复关闭软件后 OpenCode 进程泄漏问题
- 使用 taskkill /F /T 强制终止进程树 - 在 before-quit 中 await 等待服务停止完成 - 修复 stop 方法中可能的空指针问题
This commit is contained in:
@@ -17,11 +17,20 @@ const __dirname = path.dirname(__filename);
|
|||||||
electronState.setDevelopment(!app.isPackaged);
|
electronState.setDevelopment(!app.isPackaged);
|
||||||
|
|
||||||
let lastClipboardText = '';
|
let lastClipboardText = '';
|
||||||
|
let clipboardWatcherTimer: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
function stopClipboardWatcher() {
|
||||||
|
if (clipboardWatcherTimer) {
|
||||||
|
clearInterval(clipboardWatcherTimer);
|
||||||
|
clipboardWatcherTimer = null;
|
||||||
|
log.info('[ClipboardWatcher] Stopped');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function startClipboardWatcher() {
|
function startClipboardWatcher() {
|
||||||
lastClipboardText = clipboard.readText();
|
lastClipboardText = clipboard.readText();
|
||||||
|
|
||||||
setInterval(() => {
|
clipboardWatcherTimer = setInterval(() => {
|
||||||
try {
|
try {
|
||||||
const currentText = clipboard.readText();
|
const currentText = clipboard.readText();
|
||||||
if (currentText && currentText !== lastClipboardText) {
|
if (currentText && currentText !== lastClipboardText) {
|
||||||
@@ -447,7 +456,26 @@ app.whenReady().then(async () => {
|
|||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
globalShortcut.unregisterAll();
|
globalShortcut.unregisterAll();
|
||||||
opencodeService.stop();
|
opencodeService.stop();
|
||||||
|
xcOpenCodeWebService.stop();
|
||||||
|
stopClipboardWatcher();
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let isQuitting = false;
|
||||||
|
|
||||||
|
app.on('before-quit', async (event) => {
|
||||||
|
if (isQuitting) return;
|
||||||
|
isQuitting = true;
|
||||||
|
|
||||||
|
log.info('[App] before-quit received, cleaning up...');
|
||||||
|
stopClipboardWatcher();
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
opencodeService.stop(),
|
||||||
|
xcOpenCodeWebService.stop()
|
||||||
|
]);
|
||||||
|
|
||||||
|
log.info('[App] All services stopped');
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { spawn, ChildProcess } from 'child_process';
|
import { spawn, exec, ChildProcess } from 'child_process';
|
||||||
import log from 'electron-log';
|
import log from 'electron-log';
|
||||||
|
|
||||||
const OPENCODE_PORT = 4096;
|
const OPENCODE_PORT = 4096;
|
||||||
@@ -150,21 +150,33 @@ class OpenCodeService {
|
|||||||
try {
|
try {
|
||||||
log.info('[OpenCodeService] Stopping...');
|
log.info('[OpenCodeService] Stopping...');
|
||||||
|
|
||||||
this.process.kill('SIGTERM');
|
const pid = this.process.pid;
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
|
||||||
setTimeout(resolve, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.process && !this.process.killed) {
|
|
||||||
this.process.kill('SIGKILL');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.process = null;
|
this.process = null;
|
||||||
this._isRunning = false;
|
this._isRunning = false;
|
||||||
this.restartAttempts = 0;
|
|
||||||
|
|
||||||
log.info('[OpenCodeService] Stopped');
|
if (pid && process.platform === 'win32') {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
exec(`taskkill /F /T /PID ${pid}`, (error) => {
|
||||||
|
if (error) {
|
||||||
|
log.warn('[OpenCodeService] taskkill failed, process may already be dead:', error.message);
|
||||||
|
}
|
||||||
|
this.restartAttempts = 0;
|
||||||
|
log.info('[OpenCodeService] Stopped');
|
||||||
|
resolve({ success: true });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (pid) {
|
||||||
|
this.process?.kill('SIGTERM');
|
||||||
|
await new Promise<void>((resolve) => setTimeout(resolve, 1000));
|
||||||
|
if (this.process && !this.process.killed) {
|
||||||
|
this.process.kill('SIGKILL');
|
||||||
|
}
|
||||||
|
this.restartAttempts = 0;
|
||||||
|
log.info('[OpenCodeService] Stopped');
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.restartAttempts = 0;
|
||||||
return { success: true };
|
return { success: true };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
log.error('[OpenCodeService] Failed to stop:', error);
|
log.error('[OpenCodeService] Failed to stop:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user