94

我正在按照此处的指导(监听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类似的事件?

4

8 回答 8

162

您必须使用 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();
});
于 2013-02-13T19:32:22.080 回答
27

我不确定何时,但在节点 8.x 和 Windows 10 上,原始问题代码现在可以正常工作。

process.on( "SIGINT", function() {
  console.log( "\ngracefully shutting down from SIGINT (Crtl-C)" );
  process.exit();
} );

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

setInterval( () => console.log( "tick" ), 2500 );

在此处输入图像描述

也适用于 Windows 命令提示符。

于 2017-07-28T09:20:01.183 回答
8

现在它只适用 于所有平台,包括 Windows。

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

process.on('SIGINT', () => {
    console.log("Terminating...");
    process.exit(0);
});
于 2018-01-19T09:13:59.987 回答
7

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

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();
});
于 2013-09-07T20:44:25.220 回答
4

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

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

但是tty 模块文档确实提供了一个捕获按键以启动正常关闭的机制示例,但这仅适用于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();
  }
});
于 2012-04-05T05:56:41.967 回答
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");
        }
    });
}
于 2013-01-01T21:47:49.737 回答
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 上运行(在撰写本文时)。

于 2021-05-17T09:46:09.777 回答
0

Windows + Git Bash/Cygwin 解决方案:

Windows 和 Git Bash 的其他解决方案都不起作用,所以我的解决方案是简单地使用WINPTY如下启动 Node:

package.json有这个启动脚本:

"start": "winpty node app.js"

这是受类似 Python 问题在此处接受的答案的启发:

python错误抑制信号18到win32

注意: WINPTY在 Windows XP 及更高版本上运行。

于 2021-09-30T17:38:43.947 回答