Node.js如何通过进程ID独立检查进程是否正在运行?

4
我正在使用child_process来生成一个子进程并获取其PID以便于管理。下面是我的代码:
const childProcess = require('child_process');

let options = ['/c', arg1, arg2];

const myProcess = childProcess.spawn('cmd.exe', options, {
    detached: false,
    shell: false
});

let pid = myProcess.pid;

在运行时,我想使用 PID 来独立于外部验证进程是否正在运行(已完成/终止)。我想知道在 Node.js 中如何实现此操作,以及最佳方法是什么?我在 Windows 环境中运行应用程序。任何建议都将不胜感激,谢谢。

可能是重复的问题 https://dev59.com/t3vaa4cB1Zd3GeqPEo12 - A. M.
@A.M. https://dev59.com/t3vaa4cB1Zd3GeqPEo12 这个答案并不是我期望的。我想要从外部验证进程,而不是监听 exit 事件。 - ThanhPhanLe
5个回答

5
我发现is-running模块提供了一个解决方案的建议。但是,我不想为了这个目的安装新模块到我的项目中,所以我创建了自己的checkRunning()函数如下:
// Return true if process following pid is running
checkRunning(pid) {
    try {
        return process.kill(pid, 0);
    } catch (error) {
        console.error(error);
        return error.code === 'EPERM';
    }
}

根据Nodejs文档关于process.kill(pid[, signal])的说明,我可以使用process.kill()函数并指定signal参数为0来检查进程是否存在(不会杀死进程)。

我复制了文档中的一段话:

特别地,信号值为0可用于测试进程是否存在


2

谢谢,我会看一下的。 - ThanhPhanLe
你的回答非常有帮助,但我不想仅为了这个检查而安装 is-running 模块。我的解决方案是应用 process.kill 方法。感谢您的帮助,我会点赞的。 - ThanhPhanLe

1
如果你想知道子进程何时退出,可以检查exit事件
const { spawn } = require('child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);

bat.stdout.on('data', (data) => {
  console.log(data.toString());
});

bat.stderr.on('data', (data) => {
  console.log(data.toString());
});

bat.on('exit', (code) => {
  console.log(`Child exited with code ${code}`);
});

感谢@A. M.,但这不是我期望的答案。我想要独立地从外部验证进程,而不是监听“exit”事件。 - ThanhPhanLe

0

0

这里是一个代码片段作为参考

win32 (cond) {
    return new Promise((resolve, reject) => {
      const cmd = 'WMIC path win32_process get Name,Processid,ParentProcessId,Commandline,ExecutablePath'
      const lines = []

      const proc = utils.spawn('cmd', ['/c', cmd], { detached: false, windowsHide: true })
      proc.stdout.on('data', data => {
        lines.push(data.toString())
      })
      proc.on('close', code => {
        if (code !== 0) {
          return reject(new Error('Command \'' + cmd + '\' terminated with code: ' + code))
        }
        let list = utils.parseTable(lines.join('\n'))
          .filter(row => {
            if ('pid' in cond) {
              return row.ProcessId === String(cond.pid)
            } else if (cond.name) {
              if (cond.strict) {
                return row.Name === cond.name || (row.Name.endsWith('.exe') && row.Name.slice(0, -4) === cond.name)
              } else {
                // fix #9
                return matchName(row.CommandLine || row.Name, cond.name)
              }
            } else {
              return true
            }
          })
          .map(row => ({
            pid: parseInt(row.ProcessId, 10),
            ppid: parseInt(row.ParentProcessId, 10),
            // uid: void 0,
            // gid: void 0,
            bin: row.ExecutablePath,
            name: row.Name,
            cmd: row.CommandLine
          }))
        resolve(list)
      })
    })
  },

这来自于https://github.com/yibn2008/find-process/blob/master/lib/find_process.js


感谢@sinbar。但这不是我期望的答案。我想要从外部独立验证进程,而不是侦听“close”事件。 - ThanhPhanLe
这并不是监听 close 事件的问题,关键在于 'WMIC path win32_process get Name,Processid,ParentProcessId,Commandline,ExecutablePath'。它会生成一个 cmd 进程,并在其中运行一个 shell 命令并获取输出:proc.stdout.on('data', data => { lines.push(data.toString()) }) - sinbar
哦,我不想听取“data”事件的输出。 - ThanhPhanLe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接