34 lines
1.3 KiB
TypeScript
34 lines
1.3 KiB
TypeScript
import { execFile } from 'child_process';
|
|
import path from 'path';
|
|
|
|
/**
|
|
* Kill a process by PID in a cross-platform manner.
|
|
*
|
|
* On Unix: sends SIGTERM, which allows the process to handle the signal gracefully.
|
|
* On Windows: uses `taskkill /T /F /PID` to kill the entire process tree.
|
|
* - `process.kill(pid, 'SIGTERM')` on Windows does NOT actually send a signal —
|
|
* it calls TerminateProcess() which is equivalent to SIGKILL (immediate, ungraceful).
|
|
* - `taskkill /T` also kills child processes, preventing orphaned process trees.
|
|
*
|
|
* On Unix, throws if the process cannot be killed (except ESRCH — process already dead).
|
|
* On Windows, taskkill is best-effort (async fire-and-forget) to match killProcessTree() semantics.
|
|
*/
|
|
export function killProcessByPid(pid: number): void {
|
|
if (process.platform === 'win32') {
|
|
try {
|
|
const taskkillPath = path.join(
|
|
process.env.SystemRoot ?? 'C:\\Windows',
|
|
'System32',
|
|
'taskkill.exe'
|
|
);
|
|
execFile(taskkillPath, ['/T', '/F', '/PID', String(pid)], { windowsHide: true }, () => {
|
|
// Best-effort - ignore errors (process may have already exited)
|
|
});
|
|
} catch {
|
|
// taskkill failed to spawn, fall through to process.kill()
|
|
process.kill(pid, 'SIGTERM');
|
|
}
|
|
} else {
|
|
process.kill(pid, 'SIGTERM');
|
|
}
|
|
}
|