nw.js icon indicating copy to clipboard operation
nw.js copied to clipboard

Shutdown Hook

Open divinemanwah opened this issue 9 years ago • 12 comments
trafficstars

Is there a way for us to detect user shutdown to call some other functions (DB cleanup, etc.)?

Edit: Btw, I'm using nwjs-sdk-v0.16.1-win-x64

divinemanwah avatar Aug 15 '16 04:08 divinemanwah

There were two events for window close: close and closed. Does it work for you?

ghostoy avatar Aug 15 '16 07:08 ghostoy

It does work, the problem is that the callback will also be executed even if I just close the window normally.

divinemanwah avatar Aug 16 '16 05:08 divinemanwah

Any soluction? I need a listener like MS Office, that stop windows shutdown, when the document opened wasnt saved..

Or only handle function on shutdown, I tested the close and closed, but doesnt work for me.

pablozandona avatar Oct 31 '16 19:10 pablozandona

Related #4351 - to get wm_queryendsession / wm_endsession

gwicksted avatar Jan 31 '17 16:01 gwicksted

Any progress on this? I need to send a final API request before my App quits, and so far I got this workling only when the App is manually closed, but not when the system is shut down. Is there any way to accomplish that?

Connum avatar Mar 02 '19 16:03 Connum

So, here's what I tried to get this to work: (this.quitApp() is a method that tries to grecefully shut down the app, hiding it and removing it from the taskbar to make it appear closed to the user, making a final API call, then really quitting the app. I also added some logging to a file so I can see whether it worked at all.)

window.addEventListener("close", (ev) => {
    this.quitApp({description: 'quitApp() via "close" event'})
})

window.addEventListener("closed", (ev) => {
    this.quitApp({description: 'quitApp() via "closed" event'})
})

nw.Window.get().on('close', () => {
  this.quitApp({description: 'via NWWin "close" event'})
});

if (process.platform === "win32") {
  var rl = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  });

  rl.on("SIGINT", () => {
    this.quitApp({description: 'via process "SIGINT" (windows workaround)'})
  });

  rl.on("SIGTERM", () => {
    this.quitApp({description: 'via process "SIGTERM" (windows workaround)'})
  });

  rl.on("WM_ENDSESSION", () => {
    this.quitApp({description: 'via process "WM_ENDSESSION" (windows workaround)'})
  });

  rl.on("WM_QUIT", () => {
    this.quitApp({description: 'via process "WM_QUIT" (windows workaround)'})
  });
}

process.on("SIGINT", () => {
  this.quitApp({description: 'via process "SIGINT"'})
});

process.on("SIGTERM", () => {
  this.quitApp({description: 'via process "SIGTERM"'})
});

// @ts-ignore
process.on("WM_ENDSESSION", () => {
  this.quitApp({description: 'via process "WM_ENDSESSION"'})
});

// @ts-ignore
process.on("WM_QUIT", () => {
  this.quitApp({description: 'via process "WM_ENDSESSION"'})
});

process.on("exit", () => {
  this.quitApp({description: 'via process "exit" event'})
});

const exitHook = require('exit-hook');
exitHook(() => {
  this.quitApp({description: 'via exit-hook'})
});

When I use

taskkill /im nw.exe

, some of these events actually get triggered and logged and the API call is being executed. But when I shut down the PC via start menu or log out of my current user profile, nothing is being triggered, the App is being shut down forcefully and no API call is made.

Connum avatar Mar 04 '19 07:03 Connum

I didn't think WM_QUERYENDSESSION works as a signal but through windows messaging and wndproc.

https://docs.microsoft.com/en-us/windows/desktop/shutdown/wm-queryendsession

I've not done this before in node, only python. But it seems the node-win32-api package has an example of using wndproc in their create window example. https://github.com/waitingsong/node-win32-api

bluthen avatar Mar 04 '19 15:03 bluthen

Interesting! So if I get that right, you would basically create a hidden window with node-win32-api and listen to the message there, prevent shutdown and meanwhile trigger any graceful shutdown methods in your nwjs app? Can you be sure that the nwjs process will not be terminated before the window you created with wndproc? It would be great if that were possible with nwjs directly...

Connum avatar Mar 04 '19 16:03 Connum

Yes also when I did it with python I created another window. I guess I should have noted in my previous message, I was listening for login switches rather than shutdown. So I never tried to do something before shutdown. That would be a good thing for the app I'm working on to do, now that I think about it.

So I can't say definitively if it would close those other windows, you'll have to try it. I guess I mainly trying to point out that WM_QUERYENDSESSION is not a signal, and hopefully point you in a slightly better direction.

bluthen avatar Mar 04 '19 18:03 bluthen

I'm stuck trying to implement the win32-api example, it doesn't seem to play well with webpack, but even when I use nw.require() instead, I get a bunch of error messages... It also seems like a bit of an overkill for a feature I can't be the only nwjs user in the world to need.

It would be great if the nwjs core developers would have something to add. In my naive imagination it shouldn't be too hard to pass along the OS's window messages to the nwjs application...

Connum avatar Mar 06 '19 12:03 Connum

I agree this would be both challenging to implement as a user of nwjs and likely trivial for the nwjs team to hook and perform a callback. In the meantime you’ll probably have to hack something together as proposed and, while the concept is simple, if you haven’t done it before, it could be quite daunting.

Just note that, even with the hook developed by the nwjs team, your app could be killed by the system before your api call finishes (there are several factors in play).

And if you implement a hack, there are several more factors: if it’s a second window it may not get to your code and the process may have exited (depending on nwjs implementation). Worse, it could be non-deterministic.

Best approach would be to fork nwjs and hook it yourself and submit a PR so it gets into master. I don’t have nwjs building from source or I’d take a stab at it.

gwicksted avatar Mar 06 '19 14:03 gwicksted

I'm trying to run a background app but it seems it's hard to kill on exit properly.

pmingkr avatar Nov 07 '23 03:11 pmingkr