How to detect if my Windows application has ended? - c++

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.

Related

How to get Notified when a background program get closed in Windows?

the Program entry point function is WinMain
and it doesn't create a Window so it runs in the background.
I want to get a notification when the program is closed like: by the user through task manager or through system shutdown so I can save some progress.
something like the windows messages WM_QUITE but I can't access that as far as I know cuz i don't create a window
If there is no window, you may consider modifying the program registration as a DLL service plug-in.
The service also has no window and executes in the background.
The process is closed. Only the kernel callback knows that a process is killed. There will be no event whether the R3 process is closed.
Unless you have another process intermittently scanning the process list continuously.
Registering as a service at least you can receive event callbacks when your service is stopped by others.
CreateServiceW
https://learn.microsoft.com/zh-cn/windows/win32/services/installing-a-service
Is the background program something that your own code started, using CreateProcess()? If so, you can use the process handle (hProcess in the PROCESS_INFORMATION structure) in functions like WaitForSingleObject() etc. to check if the process still runs.

how to handle your windows application being force closed?

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

Interaction with Windows rebooting/shutdown

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
}

Creating a watchdog to capture minidumps

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?

C++ - Totally suspend windows application

I am developing a simple WinAPI application and started from writing my own assertion system.
I have a macro defined like ASSERT(X) which would make pretty the same thing as assert(X) does, but with more information, more options and etc.
At some moment (when that assertion system was already running and working) I realized there is a problem.
Suppose I wrote a code that does some action using a timer and (just a simple example) this action is done while handling WM_TIMER message. And now, the situation changes the way that this code starts throwing an assert. This assert message would be shown every TIMER_RESOLUTION milliseconds and would simply flood the screen.
Options for solving this situation could be:
1) Totally pause application running (probably also, suspend all threads) when the assertion messagebox is shown and continue running after it is closed
2) Make a static counter for the shown asserts and don't show asserts when one of them is already showing (but this doesn't pause application)
3) Group similiar asserts and show only one for each assert type (but this also doesn't pause application)
4) Modify the application code (for example, Get / Translate / Dispatch message loop) so that it suspends itself when there are any asserts. This is good, but not universal and looks like a hack.
To my mind, option number 1 is the best. But I don't know any way how this can be achieved. What I'm seeking for is a way to pause the runtime (something similiar to Pause button in the debugger). Does somebody know how to achieve this?
Also, if somebody knows an efficient way to handle this problem - I would appreciate your help. Thank you.
It is important to understand how Windows UI programs work, to answer this question.
At the core of the Windows UI programming model is of course "the message" queue". Messages arrive in message queues and are retrieved using message pumps. A message pump is not special. It's merely a loop that retrieves one message at a time, blocking the thread if none are available.
Now why are you getting all these dialogs? Dialog boxes, including MessageBox also have a message pump. As such, they will retrieve messages from the message queue (It doesn't matter much who is pumping messages, in the Windows model). This allows paints, mouse movement and keyboard input to work. It will also trigger additional timers and therefore dialog boxes.
So, the canonical Windows approach is to handle each message whenever it arrives. They are a fact of life and you deal with them.
In your situation, I would consider a slight variation. You really want to save the state of your stack at the point where the assert happened. That's a particularity of asserts that deserves to be respected. Therefore, spin off a thread for your dialog, and create it without a parent HWND. This gives the dialog an isolated message queue, independent of the original window. Since there's also a new thread for it, you can suspend the original thread, the one where WM_TIMER arrives.
Don't show a prompt - either log to a file/debug output, or just forcibly break the debugger (usually platform specific, eg. Microsoft's __debugbreak()). You have to do something more passive than show a dialog if there are threads involved which could fire lots of failures.
Create a worker thread for your debugging code. When an assert happens, send a message to the worker thread. The worker thread would call SuspendThread on each thread in the process (except itself) to stop it, and then display a message box.
To get the threads in a process - create a dll and monitor the DllMain for Thread Attach (and Detach) - each call will be done in the context of a thread being created (or destroyed) so you can get the current thread id and create a handle to use with SuspendThread.
Or, the toolhelp debug api will help you find out the threads to pause.
The reason I prefer this approach is, I don't like asserts that cause side effects. Too often Ive had asserts fire from asynchronous socket processing - or window message - processing code - then the assert Message box is created on that thread which either causes the state of the thread to be corrupted by a totally unexpected re-entrancy point - MessageBox also discards any messages sent to the thread, so it messes up any worker threads using thread message queues to queue jobs.
My own ASSERT implementation calls DebugBreak() or as alternative INT 3 (__asm int 3 in MS VC++). An ASSERT should break on the debugger.
Use the MessageBox function. This will block until the user clicks "ok". After this is done, you could choose to discard extra assertion failure messages or still display them as your choice.