Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

82 Zeilen
1.9 KiB

  1. import { spawn } from 'node:child_process';
  2. export function startProcess(command, args, options = {}) {
  3. const child = spawn(command, args, {
  4. cwd: options.cwd,
  5. env: { ...process.env, ...(options.env || {}) },
  6. shell: process.platform === 'win32',
  7. stdio: ['ignore', 'pipe', 'pipe'],
  8. });
  9. const output = [];
  10. child.stdout.on('data', (chunk) => output.push(chunk.toString()));
  11. child.stderr.on('data', (chunk) => output.push(chunk.toString()));
  12. child.once('exit', (code) => {
  13. if (code !== null && code !== 0) {
  14. output.push(`\nprocess exited with code ${code}\n`);
  15. }
  16. });
  17. return { child, output };
  18. }
  19. function hasExited(child) {
  20. return child.exitCode !== null || child.signalCode !== null;
  21. }
  22. function waitForExit(child, timeoutMs) {
  23. if (!child || hasExited(child)) return Promise.resolve(true);
  24. return new Promise((resolve) => {
  25. let settled = false;
  26. let timer;
  27. const finish = (exited) => {
  28. if (settled) return;
  29. settled = true;
  30. clearTimeout(timer);
  31. child.off('exit', onExit);
  32. child.off('close', onExit);
  33. resolve(exited);
  34. };
  35. const onExit = () => finish(true);
  36. child.once('exit', onExit);
  37. child.once('close', onExit);
  38. timer = setTimeout(() => finish(false), timeoutMs);
  39. timer.unref();
  40. });
  41. }
  42. function killWindowsProcessTree(pid) {
  43. if (!pid) return Promise.resolve();
  44. return new Promise((resolve) => {
  45. const killer = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], {
  46. stdio: 'ignore',
  47. });
  48. killer.once('error', resolve);
  49. killer.once('exit', resolve);
  50. });
  51. }
  52. export async function stopProcess(child) {
  53. if (!child || hasExited(child)) return;
  54. if (process.platform === 'win32') {
  55. await killWindowsProcessTree(child.pid);
  56. await waitForExit(child, 5000);
  57. return;
  58. }
  59. child.kill('SIGTERM');
  60. const exited = await waitForExit(child, 5000);
  61. if (exited) return;
  62. child.kill('SIGKILL');
  63. await waitForExit(child, 5000);
  64. }