Quit gracefully when Ctrl-C is pressed in console
elisee opened this issue · comments
- Electron version: v0.37.7
- Operating system: Windows 10 (64-bit)
Hi,
In Node.js, listening for the SIGINT
event cancels its default behavior of exiting the process.
In Electron, the SIGINT
event handler is called but the process still exits ASAP so the event handler will be interrupted randomly while it's doing its thing. For instance, running the following with electron index.js
:
setTimeout(() => { /* Just to keep process running */ }, 1000000);
process.on("SIGINT", () => {
console.log("Caught SIGINT. Exiting in 5 seconds.");
setTimeout(() => {
console.log("This should appear in the Electron console but the process will be long killed.");
process.exit(0);
}, 5000);
});
Prints for instance Caug
or Caught S
on my PC right before exiting and the rest of the function doesn't get executed. I believe that's not intended behavior.
For GUI programs it is very unreliable to handle quitting with SIGINT signal, in Electron the SIGINT signal is hijacked to call app.quit
instead. So you can use the before-quit
or will-quit
event to handle quitting.
Neither before-quit
nor will-quit
are called on my machine (Windows 10 64-bit, Electron v0.37.7) when closing the app with Ctrl+C
in a terminal (thus sending SIGINT
to it).
setTimeout(() => { /* Just to keep process running */ }, 1000000);
const electron = require("electron");
electron.app.on("before-quit", (event) => {
// This is never called! Replacing before-quit with will-quit doesn't help.
console.log("Caught before-quit. Exiting in 5 seconds.");
event.preventDefault();
setTimeout(() => { process.exit(0); }, 5000);
});
There is no SIGINT
on Windows, pressing Ctrl+C
just kills the program, as far as I know there is no way to prevent that unless the program acts like a virus.
Node.js catches Ctrl+C
and lets me handle it as SIGINT
. It may be emulation, but it's still handled by the SIGINT
handler. And Electron sort of does it too, except it terminates the program in the middle of the handler.
Maybe there's a way that Electron can check for a registered process.on("SIGINT", ...)
handler and give control to it instead of initiating its shutdown sequence, rather than doing both in parallel.
Relevant section from the Node.js process
API documentation:
SIGINT from the terminal is supported on all platforms, and can usually be generated with CTRL+C (though this may be configurable). It is not generated when terminal raw mode is enabled.
Ah I see, so in Node they use SetConsoleCtrlHandler
to catch console control events to emulate the SIGINT
event, it would probably be harder for us to do in Electron since Electron is a GUI program and SetConsoleCtrlHandler
is not supposed to work.
However we should have at least a decent way to handle a situation like this, we can probably follow the behavior on OS X that calls app.quit
when Ctrl-C is pressed, so app shuts down gracefully.
Can confirm that process.on('SIGINT') is called running as node (6.2.0), not as electron (1.2.3), on Ctrl-C
I'm doing this on command line, there is no UI but as you say the app may be run as GUI
I'd very much Electron to work same way as node.
Run this in Windows cmd prompt and behold the very weird behaviour
Windows 7:
- app.on('ready') is called as expected
- When run the app executes, electron.exe processes are loaded, and then app falls back to command line
- I can see electron.exe in Task Manager.
- Do some stuff on cmd.
- Then do a Ctrl-C and see WTF printed from the SIGINT handler, and the electron.exe processes killed.
- app.on('before-quit') is not called
OS X 10.11 - do Ctrl C
- SIGINT handler NOT called
- app.on('before-quit') called
try {
var {app} = require('electron')
}
catch (e)
{
}
if (app)
{
app.on('before-quit',function()
{
console.log('smoo')
})
app.on('ready',function()
{
console.log('smee')
})
}
process.on("SIGINT", function () {
console.log('WTF')
process.exit(0)
});
After looking into this, I'm afraid this is a limitation of Window. Since Electron is an GUI app, there is no way to catch the Ctrl-C event from Windows, even when we setup a handle with SetConsoleCtrlHandler
, Windows still kills the process anyway.
So I'm closing this as won't fix.
I've found a weird thing: when I press Ctrl+C
, a close
event of the focused BrowserWindow is triggered, instead of a app.quit()
.
How could I distinguish whether the close
event is caused by app.quit
or user normal close
in main process?
Sry for necroposting, but ctrl-c doesn't seem to be caught in ubuntu as well (using xfce terminal to be specific), should I create a new issue?
On a side note - I'm also unable to catch anything and do a graceful shutdown on ubuntu reboot... this exit handling feels like a mess, to be honest.