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

Windowsnode.js

Windows Problem Overview


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?

Windows Solutions


Solution 1 - Windows

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 2 - Windows

I'm not sure as of when, but on node 8.x and on Windows 10 the original question code simply works now.

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

enter image description here

also works with a windows command prompt.

Solution 3 - Windows

Nowadays it just works on all platforms, including Windows.

The following code logs and then terminates properly on Windows 10:

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

Solution 4 - Windows

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

Solution 5 - Windows

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

Solution 6 - Windows

Nothing above worked for me, so workaround has been to have a readline hanging and catch the signal from there.

Here my solution:

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

It's quite vanilla, it's asynchronous, and it works both on MacOS 11.3 and Windows 10 (at the time of writing).

Solution 7 - Windows

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

Solution 8 - Windows

Windows + Git Bash/Cygwin solution:

None of the other solutions for Windows and Git Bash worked, so my solution was to simply use WINPTY as follows to launch Node:

My package.json has this start script:

"start": "winpty node app.js"

This was inspired by the accepted answer here for similar Python issue:

https://stackoverflow.com/questions/50110571/python-error-suppressing-signal-18-to-win32/50120613

Note: WINPTY runs on Windows XP and beyond.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionQ 4View Question on Stackoverflow
Solution 1 - WindowsGabriel LlamasView Answer on Stackoverflow
Solution 2 - WindowsMeirion HughesView Answer on Stackoverflow
Solution 3 - WindowsHeinrich UlbrichtView Answer on Stackoverflow
Solution 4 - Windowstim-montagueView Answer on Stackoverflow
Solution 5 - WindowsPero P.View Answer on Stackoverflow
Solution 6 - WindowspierpytomView Answer on Stackoverflow
Solution 7 - WindowsmekwallView Answer on Stackoverflow
Solution 8 - Windowsjava-addict301View Answer on Stackoverflow