feat: implement menu service for context menu management
feat: add provider API service for managing provider accounts and keys feat: create provider runtime sync service for agent runtime management feat: introduce script execution service for running automation scripts feat: develop script store service for managing script metadata and storage feat: implement theme service for managing application theme settings feat: add updater service for handling application updates feat: create window service for managing application windows and their states
This commit is contained in:
105
electron/service/execute-script-service.ts
Normal file
105
electron/service/execute-script-service.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { utilityProcess } from 'electron';
|
||||
import log from 'electron-log';
|
||||
|
||||
|
||||
export class executeScriptService extends EventEmitter {
|
||||
// 执行脚本
|
||||
async executeScript(
|
||||
scriptPath: string,
|
||||
options: Record<string, any>,
|
||||
taskId?: string,
|
||||
subTaskId?: string,
|
||||
): Promise<{ success: boolean; exitCode: number | null; stdoutTail: string; stderrTail: string; error?: string }> {
|
||||
const MAX_TAIL = 32 * 1024;
|
||||
|
||||
const appendTail = (current: string, chunk: string) => {
|
||||
const next = current + chunk;
|
||||
return next.length > MAX_TAIL ? next.slice(next.length - MAX_TAIL) : next;
|
||||
};
|
||||
|
||||
return await new Promise((resolve) => {
|
||||
try {
|
||||
const roomType = options?.roomType ?? '';
|
||||
const startTime = options?.startTime ?? '';
|
||||
const endTime = options?.endTime ?? '';
|
||||
const operation = options?.operation ?? '';
|
||||
const tabIndex = options?.tabIndex ?? '';
|
||||
const channels = options?.channels ?? '';
|
||||
const startTabIndex = options?.startTabIndex ?? '';
|
||||
|
||||
const child = utilityProcess.fork(scriptPath, [], {
|
||||
env: {
|
||||
...process.env,
|
||||
ROOM_TYPE: String(roomType),
|
||||
START_DATE: String(startTime),
|
||||
END_DATE: String(endTime),
|
||||
OPERATION: String(operation),
|
||||
TAB_INDEX: String(tabIndex),
|
||||
CHANNELS: typeof channels === 'string' ? channels : JSON.stringify(channels),
|
||||
START_TAB_INDEX: String(startTabIndex),
|
||||
},
|
||||
stdio: 'pipe'
|
||||
});
|
||||
|
||||
let stdoutTail = '';
|
||||
let stderrTail = '';
|
||||
|
||||
if (child.stdout) {
|
||||
child.stdout.on('data', (data: Buffer) => {
|
||||
const text = data.toString();
|
||||
stdoutTail = appendTail(stdoutTail, text);
|
||||
log.info(`stdout: ${text}`);
|
||||
|
||||
if (text.includes('__ZN_PROGRESS__')) {
|
||||
try {
|
||||
const jsonStr = text.split('__ZN_PROGRESS__')[1]?.trim();
|
||||
if (jsonStr) {
|
||||
const parsed = JSON.parse(jsonStr);
|
||||
this.emit('progress', { taskId, subTaskId, ...parsed });
|
||||
}
|
||||
} catch {
|
||||
// ignore invalid JSON
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('stdout', { taskId, subTaskId, text });
|
||||
});
|
||||
}
|
||||
|
||||
if (child.stderr) {
|
||||
child.stderr.on('data', (data: Buffer) => {
|
||||
const text = data.toString();
|
||||
stderrTail = appendTail(stderrTail, text);
|
||||
log.info(`stderr: ${text}`);
|
||||
this.emit('stderr', { taskId, subTaskId, text });
|
||||
});
|
||||
}
|
||||
|
||||
// utilityProcess doesn't throw 'error' directly like child_process, but we can catch spawn errors or just resolve on exit
|
||||
// Electron's utilityProcess emits 'exit' instead of 'close' for completion
|
||||
child.on('exit', (code: number) => {
|
||||
log.info(`子进程退出,退出码 ${code}`);
|
||||
resolve({
|
||||
success: code === 0,
|
||||
exitCode: code,
|
||||
stdoutTail,
|
||||
stderrTail,
|
||||
...(code === 0 ? {} : { error: `Script exited with code ${code}` }),
|
||||
});
|
||||
});
|
||||
} catch (error: any) {
|
||||
resolve({
|
||||
success: false,
|
||||
exitCode: null,
|
||||
stdoutTail: '',
|
||||
stderrTail: '',
|
||||
error: error?.message || '运行 Node 脚本时出错',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user