Save data before shutdown or reboot ?

mikkevin

Member
Joined
Nov 5, 2009
Messages
10
Programming Experience
10+
I've got a small reminder application I wrote in VB Express 2008. The main app autostarts with Windows and sits in the system tray all the time. Now, I need to save the time (sorta timestamp) it closes/terminates to a file. It works fine when the app is terminated by myself but doesn't when when I shutdown/reboot Windows. The code that saves the timestamp to a file resides in FormClosing event. But for some reason it doesn't fire or the code to save the file doesn't get executed when I shut down/reboot windows.

Is there a way, probably thru' Win API to register my app with Windows, so that windows actually waits for my app to terminate in a sane way after saving the data. I remember of reading about this possibility somewhere, I don't remember now.

Any help is greatly appreciated. Thanks.
 
Are you sure your code is not filtering CloseReason? I get the event also for WindowsShutDown reason:
FormClosing 05.11.2009 11:22:58 CloseReason UserClosing
FormClosing 05.11.2009 11:23:42 CloseReason WindowsShutDown
Another possibility could be that you are tying up the UI thread with data processing and preventing event processing, the shutdown could then kill your process and you would get no FormClosing event.
 
Thanks for the reply.

Personally I don't see anything that might prevent FormClosing event to be skipped. This is what I've got under FormClosing event:
My.Computer.FileSystem.WriteAllText(My.Application.Info.DirectoryPath & "\Timestamp", Now, False)
Shutdown()

The way I've written this app is that, it uses a dummy WinForm (with no border, no controls on it and hidden all the time) just so I can get it to sit in the sytem tray. The Form_Load method sets up the system tray icon and calls a function which in turn start a thread. This thread, does some data processing and calls SetWaitableTimer API function and blocks (in an infinite loop) on the API function MsgWaitForMultipleObjects specifying QS_ALLINPUT as the WakeMask.

So, while the dummy form is sitting in the system tray, the thread I mentioned above is running in the background. When the system shutsdown or reboots, ideally the FormClosing should get called which, in turn calls the function Shutdown as is seen in the above code block, which in turn does the cleaning up and aborts the MsgWaitForMultipleObjects call.

Things work perfectly when I close the app manually but, looks like windows simply aborts the thread and terminates the system tray form without triggering the FormClosing event. So, quite possibly, it looks like the latter part of your reply is seemingly in action here !

Oh ! I must mention that I'm a VB6 guy and am new to this .Net stuff. I've never encountered such situation before (i.e being unable to save data before the app is terminated).

Thanks again.
 
Without the worker thread you should get the same result I did, because I had the same setup. A worker thread in itself is not a problem for the message loop of the app, but what you're doing in the thread might trouble it. So this is where you should look into things. I'm not familiar with the MsgWaitForMultipleObjects function other than what the docs says, it seems QS_ALLINPUT triggers by any message in queue, but as long as you don't meddle with the messages I don't see how this would affect the apps regular message loop. If you're listening to messages you can with .Net override the forms WndProc method or use Application.AddMessageFilter Method.
 
Thanks a lot for the advice JohnH. Sorry, I couldn't get back on this earlier as, I wanted to test it out for a while.

All I'd done is to include a WndProc override and things are working just right. There occasionally seems to be a problem with SetEvent API call though. I'm calling SetEvent to set a user defined event which would be returned by MsgWaitForMultipleObjects and the loop in which MsgWaitForMultipleObjects is running is terminated. Thats how I'm getting the MsgWaitForMultipleObjects loop and hence the thread to terminate when there's a need for it. Occasionally SetEvent fails with an error message "Trying to access shared or read only memory ....". This has been happening after I included the WndProc override, occasionally though.

Thanks again.

Cheers.
 
Back
Top