1

Could anyone tell me how to ensure some code in my program gets executed when its process exits or gets killed?

The destroyer only gets called when it exits normally. But I want my code get executed when it's killed by a system shutdown or task manager.

The platform is Windows and I don't mind using platform specific code if it's needed.

EternalWind
  • 137
  • 9
  • The problem is that anything that force-closes your app will probably call [TerminateProcess](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx) . According to the description for that API, "this function stops execution of all threads within the process and requests cancellation of all pending I/O." Basically your process will be killed ASAP with no guaranteed chance to save its state. If there's an I/O operation in progress it _might_ succeed, but there's no guarantee that it won't be canceled instead. – cf- Feb 22 '14 at 11:01
  • Your best (only?) bet is to make a second app that will do nothing but watch the first and run your shutdown code when the first app closes. But then you run the risk of your watcher app being killed before your primary app. So your primary app would have to include code to watch the watcher app and restart it if necessary. – cf- Feb 22 '14 at 11:03
  • @computerfreaker Thanks for the reply. How about a system shutdown? Does that use TerminateProcess as well? – EternalWind Feb 22 '14 at 16:35
  • I believe normal system shutdown uses `ExitWindowsEx` or `InitiateShutdown(Ex)`. You shouldn't need to worry _too_ much about a force-kill there, though; my understanding is that, during a normal shutdown, every process is given a chance to shut down normally (look up `WM_QUERYENDSESSION`/`WM_ENDSESSION`) before being force-killed. Someone _could_ call `InitiateSystemShutdown(Ex)` with `bForceAppsClosed` set to true or `ExitWindowsEx` with `EWX_FORCE` if they wanted, though, so once again there's no guarantee you'll have a chance to save anything. – cf- Feb 22 '14 at 20:16
  • If you want to do the two-process thing, look into [SetProcessShutdownParameters](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686227(v=vs.85).aspx) . You can use that to tell Windows to shut down your main app before your watcher app. There's still no protection against sudden force-kills or system crashes, but under normal shutdown circumstances you might find it helpful. – cf- Feb 22 '14 at 20:22
  • @computerfreaker It seems WM_QUERYENDSESSION does work but only with a window. So I decided to use a hidden window to do the trick. Anyways, thanks for pointing that out. – EternalWind Feb 24 '14 at 07:40

3 Answers3

5

You can't. What if the user pulls out the power cord?

user253751
  • 57,427
  • 7
  • 48
  • 90
1

Ending a task from Task Manager or from a Windows shutdown will both give the process a chance to shutdown gracefully by sending messages such as WM_CLOSE, which you can use to close down your process gracefully. However, as per @immibis answer, there are scenarios where this cannot be guaranteed.

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • "End Task" will send a WM_CLOSE, but "End Process" will not. – user253751 Feb 22 '14 at 08:54
  • It is the same in Un*x - Get sent a SIGTERM. Given some time then it gets the knife with SIGKILL – Ed Heal Feb 22 '14 at 11:37
  • Thanks for the reply. Does a background process(no window) also get this message when it's ended? Since this is a window message I wonder if may not work for such processes. – EternalWind Feb 22 '14 at 16:48
  • @EternalWind Have a look [here](http://stackoverflow.com/questions/3155782/what-is-the-difference-between-wm-quit-wm-close-and-wm-destroy-in-a-windows-pr). `WM_QUIT` is sent to every thread of a process. – StuartLC Feb 22 '14 at 16:53
  • WM_QUIT sounds like what I need. I will try it out tomorrow. Thanks! – EternalWind Feb 22 '14 at 17:19
  • Tried it but it's not working for a background process without a window. Only the process with a window will receive WM_QUIT. – EternalWind Feb 23 '14 at 04:11
1

Assuming that the program is crashing in a more-or-less control way perhaps atexit is the best bet

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • atexit appears to be a Linux thing, and the question is specifically about Windows. – cf- Feb 22 '14 at 11:04
  • @computerfreaker - From the horses mouth http://msdn.microsoft.com/en-us/library/tze57ck3.aspx – Ed Heal Feb 22 '14 at 11:28
  • I stand corrected. Still not quite what the question is looking for, though: "The atexit function is passed the address of a function (func) to be called when the program terminates normally." I don't believe a force-crash counts as normal termination. – cf- Feb 22 '14 at 11:31
  • 1
    I said a controlled way. Pulling the plug, memory getting corrupted all bets are off. But a signal, throwing an exception is more controlled – Ed Heal Feb 22 '14 at 11:35
  • Agreed. I'll +1 to get rid of your downvote, since your answer does cover part of the original question. As you say, though, all bets are off when the process is being hard-killed, so there's really no good answer for the other half of the question. – cf- Feb 22 '14 at 11:39
  • Thanks for replying. But I've tried this and it does not work if the process is ended by Task Manager or system shutdown. – EternalWind Feb 22 '14 at 16:44
  • @EternalWind - I will give it a go on monday – Ed Heal Feb 22 '14 at 16:49