atexit equivalent for wxApp? (Task Manager End Process) Topic is solved
atexit equivalent for wxApp? (Task Manager End Process)
I have a wxTaskBarIcon base application. Upon exit it must perform some cleanup and some system validity check (Windows XP/Vista).
When exiting via context menu (EVT_MENU ==> wxTaskBarIcon::OnMenuExit()), there is no problem: not only can I perform the validity check in wxTaskBarIcon::OnMenuExit() but wxApp::OnExit() is invoked as well.
However, when terminating my application via Task Manager's 'End Process' button - or by logging off the account - neither wxTaskBarIcon::OnMenuExit() nor wxApp::OnExit() get called.
I even tried wxApp::OnFatalException() (after enabling ::wxHandleFatalExceptions() of course) - to no avail.
Once upon a time, when I used plain C/C++, I was able to handle such ungraceful exits using
atexit().
What are my options in a wxApp based applications? Is it not possible to handle signals in wxWidgets?
What am overlooking here?
Thanks,
Dave
P.S. In my search for an answer I found the following thread http://forums.wxwidgets.org/viewtopic.php?t=19010 but its conclusion is incorrect: EVT_CLOSE is *not* called when terminating the application via Task Manager's End Process button.
When exiting via context menu (EVT_MENU ==> wxTaskBarIcon::OnMenuExit()), there is no problem: not only can I perform the validity check in wxTaskBarIcon::OnMenuExit() but wxApp::OnExit() is invoked as well.
However, when terminating my application via Task Manager's 'End Process' button - or by logging off the account - neither wxTaskBarIcon::OnMenuExit() nor wxApp::OnExit() get called.
I even tried wxApp::OnFatalException() (after enabling ::wxHandleFatalExceptions() of course) - to no avail.
Once upon a time, when I used plain C/C++, I was able to handle such ungraceful exits using
atexit().
What are my options in a wxApp based applications? Is it not possible to handle signals in wxWidgets?
What am overlooking here?
Thanks,
Dave
P.S. In my search for an answer I found the following thread http://forums.wxwidgets.org/viewtopic.php?t=19010 but its conclusion is incorrect: EVT_CLOSE is *not* called when terminating the application via Task Manager's End Process button.
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
-
- Experienced Solver
- Posts: 72
- Joined: Fri Feb 20, 2009 7:13 pm
- Location: $(#wx)\src
Thanks, but this is exactly what I was not looking for.computerquip wrote:http://docs.wxwidgets.org/2.6/wx_window ... rview.html
In my original message I described that I already handle graceful exit perfectly. The problem is only when closing the application via Task Manager or by logging off (in those cases, the aforementioned URL is irrelevant).
Additional ideas are welcome.
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
to my best knowledge it's not possible (at all) in Win32 to catch killing a process through taskmanager (i'd gladly be corrected here as i tried it myself and didn't find a way)
To catch system shutdown or user logoff you can use wxCloseEvent in wxWidgets:
http://docs.wxwidgets.org/stable/wx_wxc ... closeevent
To catch system shutdown or user logoff you can use wxCloseEvent in wxWidgets:
http://docs.wxwidgets.org/stable/wx_wxc ... closeevent
Use the source, Luke!
Perhaps I have a misconception here, but isn't wxCloseEvent same as EVT_CLOSE?doublemax wrote:To catch system shutdown or user logoff you can use wxCloseEvent in wxWidgets:
http://docs.wxwidgets.org/stable/wx_wxc ... closeevent
If so, I could swear that I tried this already (my code is full of EVT_CLOSE / OnCloseWindow() handlers - they are all invoked nicely when I exit the program nicely (i.e. via context menu item in the taskbaricon), but when the application is terminated via Task Manager (or user logoff), they are not called for some reason.
Hmmm... perhaps I am missing something. Are you sure they will be invoked on user logoff?
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
i was referring to EVT_QUERY_END_SESSION and EVT_END_SESSION.
They need to get handled at wxApp level (not in your wxFrame)
And yes, i'm sure they will get called.
However, there was an important change regarding this in 2.9.x which was not backported to 2.8.9. If you use 2.8.9 you might want to consider backporting the changes in wxApp::OnEndSession in /wx/src/msw/app.cpp (it's only a few lines)
They need to get handled at wxApp level (not in your wxFrame)
And yes, i'm sure they will get called.
However, there was an important change regarding this in 2.9.x which was not backported to 2.8.9. If you use 2.8.9 you might want to consider backporting the changes in wxApp::OnEndSession in /wx/src/msw/app.cpp (it's only a few lines)
Use the source, Luke!
Thank you! I am still using 2.6.3 (yes, I know...) - I will check this and post an update.doublemax wrote:However, there was an important change regarding this in 2.9.x which was not backported to 2.8.9. If you use 2.8.9 you might want to consider backporting the changes in wxApp::OnEndSession in /wx/src/msw/app.cpp (it's only a few lines)
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
I just tried this and wxApp::OnEndSession doesn't work.
OnEndSession is not a wxApp built-in function. I first added it to the wxApp-derived class, then added it to the event table:
All this function does is log a message to a log file (using wxLogStream).
Even when exiting gracefully (via context menu) this function is not called (I can see the OnCloseWindow and wxApp::OnExit logs in the log file but not OnEndSession).
I must be implementing it incorrectly. I couldn't find a sample that actually uses EVT_END_SESSION. Any tips regarding how to implement it?
What did you mean by 'backporting'? Is there some critical code that was introduced only in 2.9.x without which EVT_END_SESSION will work?
Thanks!
P.S. in the link you supplied there is no wxApp::OnEndSession. But in a wxPython page, I found that it is actually implemented (in version 2.8.x?). Then I found a post from about a year ago that suggests a bug in the implementation:
http://lists.wxwidgets.org/pipermail/wx ... 71543.html
Now I am totally confused...
OnEndSession is not a wxApp built-in function. I first added it to the wxApp-derived class, then added it to the event table:
Code: Select all
BEGIN_EVENT_TABLE(CMyApp, wxApp)
EVT_END_SESSION(CMyApp::OnEndSession)
END_EVENT_TABLE()
Even when exiting gracefully (via context menu) this function is not called (I can see the OnCloseWindow and wxApp::OnExit logs in the log file but not OnEndSession).
I must be implementing it incorrectly. I couldn't find a sample that actually uses EVT_END_SESSION. Any tips regarding how to implement it?
What did you mean by 'backporting'? Is there some critical code that was introduced only in 2.9.x without which EVT_END_SESSION will work?
Thanks!
P.S. in the link you supplied there is no wxApp::OnEndSession. But in a wxPython page, I found that it is actually implemented (in version 2.8.x?). Then I found a post from about a year ago that suggests a bug in the implementation:
http://lists.wxwidgets.org/pipermail/wx ... 71543.html
Now I am totally confused...
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
i'm not sure if this works, if wxLogstream uses buffered output it might not have the chance to flush its buffer. try lowlevel fopen/write/closeAll this function does is log a message to a log file (using wxLogStream).
this is normal. It's not called when closing the application this way.Even when exiting gracefully (via context menu) this function is not called
by backporting i mean applying the changes from wx 2.9.x to your wx 2.6.x sources and recompile the library.What did you mean by 'backporting'? Is there some critical code that was introduced only in 2.9.x without which EVT_END_SESSION will work?
In the old version, the EVT_END_SESSION handler is the last code that will be executed in your application because Windows will kill the process immediately afterwards. That means wxApp::OnExit(), wxFrame or wxApp dtors will *not* get called.
In the new code the application terminates more "cleanly".
Use the source, Luke!
Thanks. This greatly clarifies the picture. I just downloaded version 2.8.9 as well as the daily snapshot (CVS head) and I can see the difference:
Both in 2.6.3 and 2.8.9 wxApp::OnEndSession is implemented as:
whereas in 2.9.x (2009-02-25 snapshot) it is implemented as:
Now, I see that app.h wxApp::OnEndSession is not implemented as a virtual function. I wonder whether I can simply override it in my application's wxApp-derived class. I don't feel like rebuilding 2.6.3... I prefer migrating to 2.8.9 instead (but we all know that when this is done, it takes more than just the time to build it...)
Thank you again for your great tips!
Both in 2.6.3 and 2.8.9 wxApp::OnEndSession is implemented as:
Code: Select all
if (GetTopWindow())
GetTopWindow()->Close(true);
Code: Select all
if ( !wxTopLevelWindows.empty() )
wxTopLevelWindows[0]->SetHWND(0);
const int rc = OnExit();
wxEntryCleanup();
exit(rc);
Thank you again for your great tips!
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
OK - I just finished trying this - and it still doesn't log anything to the log file.doublemax wrote: try lowlevel fopen/write/close
So, I set some breakpoints in the debugger and got the following interesting results:
Upon Windows Task Manager "End Process" call, non of these "OnExit" function are called:
- CMyApp::OnFatalException()
CMyApp::OnEndSession
CMyApp::OnExit()
AtExit() (yes, I registered an atexit() function in CMyApp init)
- CMyApp::OnExit()
AtExit()
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
You are absolutely correct - it works! and without having to recompile 2.6.3.doublemax wrote:EVT_END_SESSION should be triggered when the user logs off.
Sorry, I overlooked your distinction between Task Manager and Logoff. Now that I re-read it I see that you actually made that distinction. Thank you!doublemax wrote:like i mentioned before, i don't think it's possible to detect when your application gets killed through the task manager.
I now have to find a creative way around Windows Task Manager's "horrible" 'End Process' (I guess that there is some wisdom in creating a kill mechanism that cannot be intercepted in any way - even Notepad does not attempt to save data when killed by Task Manager).
BTW, because I overlooked the distinction between Task Manager and Logoff, I mistakenly concluded that wxLogStream is not valid in OnEndSession. This is not the case and wxLogStream works very well in OnEndSession.
wxMSW-2.6.3 / Visual C++ 2005 EE / Windows XP SP2
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)
(was: wxMSW-2.6.3 / Visual C++ 6.0 SP6 / Windows 2000 SP5)