Everyone programs console applications one time or the other. This
programming is more prevalent when people are learning to program, especially
while learning the DOS based C/C++ programming. However, when one migrates to
Windows programming, console application development takes a back seat. But the
Win32 console development holds an important place, especially when the Win32
API contains a good amount of API dedicated to console application development.
If you have noticed, even VC++, and latest development technologies like C#,
also supports console project development. Console applications are good
candidates for testing the core functionality of your Windows application
without the unnecessary overhead of a GUI.
But there's always been a sense of helplessness in regard to how to know when
certain system related events have occurred, like when user if logging off, or
the system is being shutdown, or handling control+break or control+C keyboard
events, etc. For a Windows based application, getting to know when such events
occur is no problem since they are having a message queue assigned to them that
is polled, and assuming that the concerned event is programmed for, it can be
handled pretty easily. But this isn't the case with a console application that
has no concept of a message queue.
This article intends to discuss how you can handle all kinds of console-based
events in any console application. Once you have gone through it, you will see
for yourself how trivial this seemingly helpless task is :)
Setting Console Traps
The first step in handling console application events is to setup an even
trap, technically referred to as installing an event handler. For this purpose,
we utilize the
SetConsoleCtrlHandler Win32 API that is prototyped as shown
PHANDLER_ROUTINE HandlerRoutine, BOOL Add );
HandlerRoutine parameter is a pointer to a function that has the
BOOL WINAPI HandlerRoutine(
DWORD dwCtrlType );
HandlerRoutine takes is a
DWORD parameter that tells what console
event has taken place. The parameter can take the following values:
CTRL_C_EVENT - occurs when the user presses CTRL+C, or when it is sent by
CTRL_BREAK_EVENT - occurs when the user presses CTRL+BREAK, or when it is
sent by the
CTRL_CLOSE_EVENT - occurs when attempt is made to close the console, when
the system sends the close signal to all processes associated with a given
CTRL_LOGOFF_EVENT - occurs when the user is logging off. One cannot
determine, however, which user is logging off.
CTRL_SHUTDOWN_EVENT - occurs when the system is being shutdown, and is
typically sent to services.
Upon receiving the event, the
HandlerRoutine can either choose to do some
processing, or ignore the event. If the routine chooses not to handle the event,
it should return
FALSE, and the system shall then proceed to the next installed
handler. But incase the routine does handle the event, it should then return
TRUE, after doing all the processing it requires. The
CTRL_SHUTDOWN_EVENT are typically used to perform any
cleanup that is required by the application, and then call the
Thus, the system has has some timeouts associated with these three events, which
is 5 seconds for
CTRL_CLOSE_EVENT, and 20 seconds for the other two. If the
process doesn't respond within the timeout period, Windows shall then proceed to
display the End Task dialog box to the user. If the user proceeds to end the
task, then the application will not have any opportunity to perform cleanup.
Thus, any cleanup that is required should complete well within the timeout
period. Below is an exemplification of the handler routine:
BOOL WINAPI ConsoleHandler(DWORD CEvent)
"Program being closed!","CEvent",MB_OK);
"User is logging off!","CEvent",MB_OK);
"User is logging off!","CEvent",MB_OK);
Now that we have seen how the handler routine works, lets see how to install
the handler. To do so, as mentioned earlier in the article, we use the
SetConsoleCtrlHandler API as shown below:
printf("Unable to install handler!\n");
The first parameter is a function pointer of the type
prototype has been discussed earlier. The second parameter, if set to
tries installing the handler, and if set to
FALSE, attempts the un-installation.
If either attempts are successful, the return value is
So, that's all there is to handling the console application events. After
handler is installed, your application will receive the events as and by they
come, and when the execution is about to be terminated, the handler maybe
un-installed. Pretty easy, eh :) ?
I hold Early Acheiver in MCSE 2000, MCSE NT 4.0, MCP+I, and actively involved in programming using C/C++, .NET framework, C#, Win32 API, VB, ASP and MFC.
I also have various publications to my credit at MSDN Online Peer Journal, Windows Developer Journal (http://www.wdj.com/), Developer 2.0 (http://www.developer2.com/), and PC Quest (http://www.pcquest.com/).