在node.js中,Windows等效于process.on('SIGINT')是什么?

时间:2012-04-05 01:05:18

标签: windows node.js

我正在遵循指导here(侦听SIGINT事件)以优雅地关闭我的Windows-8托管的node.js应用程序以响应Ctrl-C或服务器关闭。

但Windows没有SIGINT。我也试过了process.on('exit'),但这似乎迟到了做任何有用的事情。

在Windows上,此代码为我提供:错误:没有此类模块

process.on( 'SIGINT', function() {
  console.log( "\ngracefully shutting down from  SIGINT (Crtl-C)" )
  // wish this worked on Windows
  process.exit( )
})

在Windows上,此代码会运行,但太晚,无法做任何优雅的事情

process.on( 'exit', function() {
  console.log( "never see this log message" )
})

Windows上是否有SIGINT等效事件?

7 个答案:

答案 0 :(得分:128)

您必须使用readline模块并侦听SIGINT事件:

http://nodejs.org/api/readline.html#readline_event_sigint

if (process.platform === "win32") {
  var rl = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  });

  rl.on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  //graceful shutdown
  process.exit();
});

答案 1 :(得分:14)

我不确定何时,但在节点8.x和Windows 10上,原始问题代码现在只能运行。

enter image description here

也适用于Windows命令提示符。

答案 2 :(得分:7)

除非您需要为其他任务导入“readline”,否则我建议在程序验证它在Windows上运行后导入“readline”。此外,对于那些可能不知道的人 - 这适用于Windows 32位和Windows 64位系统(将返回关键字“win32”)。感谢Gabriel的这个解决方案。

if (process.platform === "win32") {
  require("readline")
    .createInterface({
      input: process.stdin,
      output: process.stdout
    })
    .on("SIGINT", function () {
      process.emit("SIGINT");
    });
}

process.on("SIGINT", function () {
  // graceful shutdown
  process.exit();
});

答案 3 :(得分:4)

目前节点中仍然没有支持捕获Windows控制台控件事件,因此没有POSIX信号的等价物:

https://github.com/joyent/node/issues/1553

然而,tty module documentation确实给出了一个捕获按键的机制的示例,以便启动正常关闭,但是这只适用于 ctrl + c

var tty = require('tty');

process.stdin.resume();
tty.setRawMode(true);

process.stdin.on('keypress', function(char, key) {
  if (key && key.ctrl && key.name == 'c') {
    console.log('graceful exit of process %d', process.pid);
    process.exit();
  }
});

答案 4 :(得分:4)

现在它正常工作 on all platforms,包括Windows。

以下代码记录然后在Windows 10上正确终止:

process.on('SIGINT', () => {
    console.log("Terminating...");
    process.exit(0);
});

答案 5 :(得分:0)

由于node.js 0.8,keypress事件不再存在。然而,有一个名为keypress的npm包重新实现了该事件。

使用npm install keypress安装,然后执行以下操作:

// Windows doesn't use POSIX signals
if (process.platform === "win32") {
    const keypress = require("keypress");
    keypress(process.stdin);
    process.stdin.resume();
    process.stdin.setRawMode(true);
    process.stdin.setEncoding("utf8");
    process.stdin.on("keypress", function(char, key) {
        if (key && key.ctrl && key.name == "c") {
            // Behave like a SIGUSR2
            process.emit("SIGUSR2");
        } else if (key && key.ctrl && key.name == "r") {
            // Behave like a SIGHUP
            process.emit("SIGHUP");
        }
    });
}

答案 6 :(得分:0)

以上没有对我有用,所以解决方法是挂一个 readline 并从那里捕捉信号。

这是我的解决方案:

const readline = require('readline');

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

// Flag to be able to force the shutdown
let isShuttingDown = false;

// https://nodejs.org/api/readline.html
rl.on('SIGINT', async () => {
  if (isShuttingDown) {
    logger.info("Forcing shutdown, bye.");
    process.exit();
  } else {
    if (!<yourIsCleanupNecessaryCheck>()) {
      logger.info("No cleanup necessary, bye.");
      process.exit();
    } else {
      logger.info("Closing all opened pages in three seconds (press Ctrl+C again to quit immediately and keep the pages opened) ...");
      isShuttingDown = true;
      await sleep(3000);
      await <yourCleanupLogic>();
      logger.info("All pages closed, bye.");
      process.exit();
    }
  }

function sleep(ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

它非常简单,它是异步的,并且适用于 MacOS 11.3 和 Windows 10(在撰写本文时)。