What is the Windows equivalent of process.on('SIGINT') in node.js?

Problem

I'm following the guidance here (listening for SIGINT events) to gracefully shutdown my Windows-8-hosted node.js application in response to Ctrl-C or server shutdown.

But Windows doesn't have SIGINT. I also tried process.on('exit'), but that seems to late to do anything productive.

On Windows, this code gives me: Error: No such module

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

On Windows, this code runs, but is too late to do anything graceful:

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

Is there a SIGINT equivalent event on Windows?

Problem courtesy of: pappadog

Solution

You have to use the readline module and listen for a SIGINT event:

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();
});
Solution courtesy of: Gabriel Llamas

Discussion

Currently there is still no support in node for capturing the windows console control events, so there are no equivalents to the POSIX signals:

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

However the tty module documentation does give an example of a mechanism to capture the key presses in order to initiate a graceful shutdown, but then this does only work for 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();
  }
});
Discussion courtesy of: Pero P.

Since node.js 0.8 the keypress event no longer exists. There is however an npm package called keypress that reimplements the event.

Install with npm install keypress, then do something like:

// 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");
        }
    });
}
Discussion courtesy of: Marcus Ekwall

Unless you need the "readline" import for other tasks, I would suggest importing "readline" once the program has verified that it's running on Windows. Additionally, for those who might be unaware - this works on both Windows 32-bit and Windows 64-bit systems (which will return the keyword "win32"). Thanks for this solution 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();
});
Discussion courtesy of: tfmontague

This recipe can be found in it's original form on Stack Over Flow.