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


84

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

但是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" )
})

SIGINTWindows上是否有等效事件?


今天,这个问题在我身上随机发生,我认为这与readline模块本身有关。我无法进行任何测试,但是由于添加了此模块,因此开始出现问题。
Sv443 '19

Answers:


148

您必须使用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();
});

最优秀的更新,谢谢!将其设置为答案,因为以前的答案(听按键)不再起作用。
pappadog13年

44
这是荒唐的。为什么节点核心不处理此问题?
balupton 2013年

3
因为当您收听stdin时,直到您明确发送SIGINT信号,该过程才会完成。
加布里埃尔·拉马斯

2
因此,您需要从父级向子级发送随机消息,例如:“ SIGINT”。
加布里埃尔·拉马斯

8
看起来这个问题早已解决:github.com/nodejs/node-v0.x-archive/issues/5054
SimonSimCity

23

我不确定什么时候开始,但是在节点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命令提示符。


我也注意到了这一点。Windows 7是我
面临

此方法对Windows 7上的Node 8.11.1来说适用于我-但是我是从git bash shell运行它的。以为我会先尝试简单的方法,然后就可以了。
user944849 '18

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();
});

5

如今,它仅适用 包括Windows在内的所有平台

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

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

2
在cygwin下,这对我不起作用。使用最新的Windows 10(自动更新),节点版本8.11.4。“不起作用”是指1)进程确实终止,但是2)消息未记录到控制台,并且3)创建的HTTP连接未关闭。但是,我应该补充一点,我在PowerShell下进行了尝试,并且在这里可以正常工作。但是我改用cygwin是因为PowerShell的curl命令错误。该死!
约翰·迪恩

2
直到今天,它才停止为我工作,没有明显的原因(根本没有更新),我仍然不知道为什么。公认的答案解决了它。
Sv443 '19

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();
  }
});

谢谢,一直在寻找此信息,只要我可以在服务器上为CTRL + C实施它,这对我来说就是可以接受的替代方法。+1(但是。是否知道这是否会通过在该过程中添加事件侦听器而影响性能?)
Cory Gross,

我尝试这样做,但是当我的服务器正在运行游戏循环时,stdin似乎不可用,当我使用上面的命令时,CTRL + C不起作用。
科里·格罗斯

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");
        }
    });
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.