PDA

View Full Version : Windows Shutdown Notification of Console Application



qtYoda
17th February 2012, 19:11
I'm running a QCoreApplication as a TCP/IP server. I've implemented a signal handler to get SIGINT and SIGTERM but I'm not getting notification when a user restarts or shuts down Windows (XP).

It works fine when the application receives a shutdown command from a TPC/IP client.

But I need to save files when the user shuts down Windows. How can I do this?

I have implemented the aboutToQuit() signal, but this doesn't seem to get called either.

Thanks

qtYoda
18th February 2012, 00:08
Is this a Qt problem on Windows that is known to have no solution?

wysota
18th February 2012, 14:45
No, that is not a Qt problem on Windows. What does Qt have to do with your system shutting down? Does Windows even send SIGINT or SIGTERM to processes when closing the system or did you just assume that if Unix does this, so does Windows?

AlexSudnik
18th February 2012, 15:23
Hm , actually aboutToQuit() is being emitted just fine...unless you terminate an application.So make sure that you use either
void QCoreApplication::exit ( int returnCode = 0 ) [static] or void QCoreApplication::quit () [static slot]. I think i used to have alike problems with implementation of pretty much the same feature once , but in my case the thing was that i could not handle close event right , while an application was in tray or smth. like that...But again , it was 100 % due to my ignorance rather then QT's dysfunctionality.

yeye_olive
20th February 2012, 11:30
@qtYoda

There is a way to be notified when the user closes the console or hits Ctrl+C. I have tried it and it works; you might want to try it to see if it also works when the user shuts down Windows without closing the console first (it should according to MSDN). I did the following:
1. upon initializing the application, call SetConsoleCtrlHandler() to register a handler that will get called when the console is closed or Ctrl+C is hit;
2. in the handler, forward the notification to Qt's event loop by using e.g. QCoreApplication::postEvent() with a dedicated custom event, then return TRUE;
3. do the heavy work upon receiving the custom event, then exit using e.g. QCoreApplication::quit().
Note that it is simpler than the equivalent in Unix, where you cannot do much in a signal handler. There are a number of solutions to that issue, notably using a pipe, or running sigwait() in a dedicated thread, or using the Linux-specific signalfd() system call.

qtYoda
21st February 2012, 18:50
Thanks everyone. Here is what I've tried.

When I posted I had already tried 1) connecting via "aboutToQuit" signal, and 2) the signalhandler method to get the users Ctrl-C method. Neither seemed to be getting informed when the user just shutdown or restarted via the standard "Start/Turn Off Computer" method.

So I started thinking that, since the program has no window (and no console), Windows would not inform anything. I found some online documentation that Microsoft provides a method to create a hidden "window" that is there just for the purpose of getting windows messages. So I used RegisterClassEx() and CreateWindowEx() to create the non-window "window" and hooked into the message loop with that "window". Inside the message loop I write a simple message to to file so I can see when the function is called. I know it's being called in normal situations when Windows is telling the window to shutdown via WM_QUIT/VM_CLOSE/VM_DESTROY. But its NOT calling the message hook when the user chooses to shutdown/restart. Argghhhh!

I'm begining to think that, since what I'm really doing is what is normally thought of as a "Windows Service", that I need to just implement this as a Windows Service and hook into the management paradigm for services. Any other thoughts before I start down that road would be appreciated if they might shed light on getting Windows to simply let me know when it intends to kill my program.