NodeJS-如何检测程序的其他副本



我写了一个NodeJS命令行程序,有两种模式:

  • 模式foo:永远运行,直到用户按下Ctrl+C
  • 模式栏:运行一次

如果用户已经在foo模式下运行程序,那么在模式栏中再次运行程序将导致错误。因此,当用户调用模式栏时,我希望搜索正在运行的命令行程序的所有其他现有副本并杀死它们(作为在错误发生之前防止错误发生的机制(。

在NodeJS中获取进程列表很容易,但这对我没有多大帮助。如果我只是简单地杀死所有其他节点进程,那么我可能会杀死其他不是我的程序。因此,我需要知道哪些特定的节点进程是运行我的应用程序的进程。甚至有可能询问一个过程来确定信息吗?

另一种选择是让我的程序在磁盘上写一个临时文件,或者在Windows注册表中写一个值,或者类似的东西。然后,在我的程序存在之前,我可以清理临时值。然而,这感觉像是一个不稳定的解决方案,因为如果我的程序崩溃,那么标志将永远不会被取消设置,并且将永远成为孤儿。

这个问题的正确解决方案是什么?如何终止我自己的应用程序?

我能够使用PowerShell解决此问题:

import { execSync } from "child_process";
const CWD = process.cwd();
function validateOtherCopiesNotRunning(verbose: boolean) {
if (process.platform !== "win32") {
return;
}
// From: https://securityboulevard.com/2020/01/get-process-list-with-command-line-arguments/
const stdout = execPowershell(
"Get-WmiObject Win32_Process -Filter "name = 'node.exe'" | Select-Object -ExpandProperty CommandLine",
verbose,
);
const lines = stdout.split("rn");
const otherCopiesOfMyProgram= lines.filter(
(line) =>
line.includes("node.exe") &&
line.includes("myProgram") &&
// Exclude the current invocation that is doing a 1-time publish
!line.includes("myProgram publish"),
);
if (otherCopiesOfMyProgram.length > 0) {
throw new Error("You must close other copies of this program before publishing.");
}
}
function execPowershell(
command: string,
verbose = false,
cwd = CWD,
): string {
if (verbose) {
console.log(`Executing PowerShell command: ${command}`);
}
let stdout: string;
try {
const buffer = execSync(command, {
shell: "powershell.exe",
cwd,
});
stdout = buffer.toString().trim();
} catch (err) {
throw new Error(`Failed to run PowerShell command "${command}":`, err);
}
if (verbose) {
console.log(`Executed PowerShell command: ${command}`);
}
return stdout;
}

最新更新