if a user decides to force close my application(like through the task manager) is there a way i can quickly execute some clean up code before the application closes? i'm coding in c++ btw
It depends on how the process is instructed to close. It is possible to do this upon graceful exit, but not for anything forcefully closed.
If the process is closed via TerminateProcess or ExitProcess, you won't be able to perform any graceful cleanup. TerminateProcess is how Task Manager and utilities like Sysinternals pskill end a target process. ExitProcess is called within a process but is not typically used to exit.
If the process has a message pump on one thread (typically the first thread in the process) and no other threads running that are running code whose lifetimes are independent of activity in that thread, then a WM_QUIT message will signal that the process should close (semantically, that the app should close, your process might conceivably stick around for a while for other reasons), and you can run cleanup code upon receiving the message. Depending on your needs, in a windowed app you might consider performing cleanup operations as early as WM_CLOSE or WM_DESTROY.
If you have written code in a DLL, there are notifications that you can handle in DllMain that will allow you to perform last-chance cleanup (DLL_PROCESS_DETACH), which can potentially cover the case of a process exiting without having a message pump. However, this is not a great way to perform cleanup for code that strictly relies on any C/C++ runtime (or any other DLL), as the runtime might be unloaded first.
Last, for any graceful close where you control what runs in WinMain or main, you can always do whatever cleanup you need to do before either function returns, sending control back to the windows subsystem. This is preferred and usually safest for most application needs.
If you are using a message pump, handle the WM_QUIT message.
Also: What is the difference between WM_QUIT, WM_CLOSE, and WM_DESTROY in a windows program?
EDIT
Im sorry, I read over the fact that you want to handle termination, eg by the task manager.
This might help you though: How to catch event when Task manager kill your C++ application
Related
Basically what the title says I need to detect when my program is ending like when someones clicks on end task in the task manager or something. Can anyone point me to some kind of event that handles this with an example or something? Thanks for any help given
You need to open this process. This way you will retrieve its handle. After that you can simply wait on this handle.
HANDLE h = OpenProcess(....);
WaitForSingleObject(h);
Handles of the processes and threads in many ways look like Windows event handles. Once this process or thread finishes, they get signaled.
It depends on how your app is terminated and what type of app it is.
For apps with an UI:
If the user clicks "End Task" in the task manager, you will actually receive WM_DESTROY and even WM_CLOSE messages to your message handler.
If the user simply clicks the X button of your app, obviously the above also applies.
If the user logs off or shuts down the PC, you'll receive WM_QUERYENDSESSION and WM_ENDSESSION messages.
For console apps, you can use the SetConsoleCtrlHandler function to be notified of most cases of app termination (I don't have any experience with this so can't give many details).
For services, you can use the RegisterServiceCtrlHandler function in much the same way.
For all types of apps, if the app is terminated forcibly by another process via the TerminateProcess function, there is no way to get notified:
If a process is terminated by TerminateProcess, all threads of the process are terminated immediately with no chance to run additional code. This means that the thread does not execute code in termination handler blocks. In addition, no attached DLLs are notified that the process is detaching.
For example we have a Win32 application which on close of main window hides to tray.
When user reboot or shutdown OS applications were closed in some way.
How to handle properly this closing event?
This is documented over on MSDN: Shutting Down.
Essentially you need a top-level window that listens for either WM_QUERYENDSESSION or WM_ENDSESSION or possibly both. You get an opportunity to perform shutdown related tasks when these messages arrive.
Applications with a window and message queue receive shutdown notifications through the WM_QUERYENDSESSION and WM_ENDSESSION messages. These applications should return TRUE to indicate that they can be terminated. Applications should not block system shutdown unless it is absolutely necessary. Applications should perform any required cleanup while processing WM_ENDSESSION. Applications that have unsaved data could save the data to a temporary location and restore it the next time the application starts. It is recommended that applications save their data and state frequently; for example, automatically save data between save operations initiated by the user to reduce the amount of data to be saved at shutdown.
If you wish to show UI during shutdown, perhaps because your app is performing critical actions that cannot survive interruption, then you can use ShutdownBlockReasonCreate.
If an application must block a potential system shutdown, it can call the ShutdownBlockReasonCreate function. The caller provides a reason string that will be displayed to the user. The reason string should be short and clear, providing the user with the information necessary to decide whether to continue shutting down the system.
Note that this process was changed dramatically from Vista. If you need to support XP then you may need code that behaves differently under XP. That topic is also covered on MSDN: Application Shutdown Changes in Windows Vista.
You should handle the System Shutdown Messages WM_QUERYENDSESSION and WM_ENDSESSION.
Shuting down should cause a SIGTERM or SIGINT be sent to you program.
You can handle this via .
Ref: http://www.cplusplus.com/reference/csignal/signal/
void my_handler (int param)
{
// clean up here
}
int main ()
{
signal(SIGINT my_handler); // try also SIGTERM
}
I'm trying to add the functionality of capturing mini-dumps when my program crashes. From what I've read, this is best achieved by use of another application (the watchdog) that is used to host the real application, and performs the dump.
From looking at posts such as this, I've come up with the following (both App and WatchDog are implemented in C++ using Win32):
When the watchdog starts, it creates 2 events, an ExitedOk event, and an Exception event, both of which are set to be inheritable and aren't signalled. It also creates an inheritable file mapping.
The watchdog then launches the "real app", and waits in a WaitOnMultipleObjects for either ExitedOk or Exception to be signalled.
When the app starts, it creates the same 2 events (it will inherit the handles)
The app is configured such that if it exits ok, it signals ExitedOk, or if an unhandled exception occurs, it stores the exception/thread info using the inherited filemapping, signals Exception, and then sleeps(Infinite).
If the WaitOnMultipleObjects in the watchdog is signalled with an ExitedOk, nothing happens. If it is signalled with an Exception, then it reads the exception/thread info using the filemapping, and then calls MiniDumpWriteDump.
Clearly the Sleep() is an issue. Is this best resolved through another event? Such that the App waits until the watchdog signals some "FinishedCreatingDump" event?
Secondly, I thought that the whole point of the watchdog was so that you weren't doing any work in the crashed process that is potentially unstable? If I'm understanding the workflow correctly, and that you do indeed need the SetEvent/OpenFileMapping/MapViewOfFile in the process that actually crashed, isn't that just as bad as calling MiniDumpWriteDump from it?
Is there some way to detect that a program was ended by windows task manager's "end process"?
I know that its kinda impossible to do that from within the application being ended (other than to build your app as a driver and hook ZwTerminateProcess), but I wonder if there is a way to notice it from outside.
I don't want to stop the program from terminating, just to know that it was ended by "end process" (and not by any other way).
There might be a better way - but how about using a simple flag?
Naturally, you'd have to persist this flag somewhere outside of the process/program's memory - like the registry, database, or file system. Essentially, when the app starts up, you set the flag to 'True' when the app shuts down through the normal means, you set the flag to 'False'.
Each time the application starts you can check the flag to see if it was not shut down correctly the previous time it was executed.
Open up a handle to the process with OpenProcess, and then wait on that handle using one of the wait functions such as WaitForSingleObject. You can get the exit status of the process using GetExitCodeProcess. If you need your program to remain responsive to user input while waiting, then make sure to wait on a separate thread (or you can periodically poll using a timeout of zero, but remember the performance consequences of polling -- not recommended).
When you're done, don't forget to call CloseHandle. The process object won't be fully deleted from the OS until all of its handles are closed, so you'll leak resources if you forget to call CloseHandle.
Note that there's no way to distinguish between a process exiting normally or being terminated forcefully. Even if you have a convention that your program only ever exits with a status of 0 (success) or 1 (failure) normally, some other process could call TerminateProcess(YourProcess, 1), and that would be indistinguishable from your ordinary failure mode.
According to the documentation, ExitProcess calls the entry point of all loaded DLLs with DLL_PROCESS_DETACH, whereas TerminateProcess does not. (Exiting the main function results in a call to ExitProcess, as do most unhandled exceptions.)
You might also want to look into Application Recovery and Restart.
One option might be to create a "watchdog" application (installed as a service, perhaps) that monitors WMI events for stopping a process via the ManagementEventWatcher class (in the System.Management namespace).
You could query for the death of your process on an interval or come up with some event driven way to alert of your process's demise.
Here's sort of an example (it's in C# though) that could get you started.
I'm developing a DLL in C++ which needs to write some data via a (previously established) TCP/IP connection using the write() call. To be precise, the DLL should send a little 'Process 12345 is terminating at 2007-09-27 15:30:42, value of i is 131' message over the wire when the process goes down.
Unfortunately, all the ways I know for detecting that the process is ending are apparently too late for any network calls to succeed. In particular, I tried the following approaches and the write() call returned -1 in every case:
Calling write() from the destructor of a global object.
Calling write() from a callback function registered using atexit().
Calling write() from DllMain (in case the reason argument is DLL_PROCESS_DETACH). I know that this is not a safe thing to do, but I'm getting a bit desperate. :-)
I'm aware that a DLL can't detect any process shutdown (it might have been unloaded long before the process terminates) but since the shutdown data which the DLL needs to send depends on other code in the DLL, that's acceptable. I'm basically looking for the latest moment at which I can safely perform network IO.
Does anybody know how to do this?
Consider monitoring the process from a separate watchdog process.
Determining If a Process Has Exited: http://msdn.microsoft.com/en-us/library/y111seb2(v=VS.71).aspx
Tutorial: Managing a Windows Process: http://msdn.microsoft.com/en-us/library/s9tkk4a3(v=VS.71).aspx
Consider to use Windows Job Objects.
You main program (monitoring program, which will use for example send()) can start child process suspended, place it into a Job and then resume. Then it will run in the job object. You can register notification via SetInformationJobObject with JobObjectAssociateCompletionPortInformation. Then you will be notified if in the job will be created some child process and if some process inside of job will be ended. So you will be able to send all what you need from the monitoring process. If you debug a program in Visual Studio it uses also job objects to have control under your process and all child processes which you start.
I successfully use the technique in C++ and in C#. So if you will have some problem with implementation I could post you a code example.
I suggest taking option 3. Just do your DLL loading/unloading properly and you're fine. Calling write() should work, I can't explain why it's not in your case. Is it possible that the call fails for a different reason that is unrelated?
Does it work if you call your DLL function manually from the host app?
Why? Just close the socket. If that's the only close in the program, which by your description it must be, that tells the other end that this end is exiting, and you can send the process ID information at the beginning instead of the end. You shouldn't do anything time-consuming or potentially blocking in an exit hook or static destructor.
Where is Winsock being shut down using WSACleanup? You need to make sure that your I/O completes before this happens.
You should be able to work out if this is happening by placing a breakpoint on the Win32 call in Winsock2.dll. Unload of DLLs is displayed in the output in the debug window.