Manejar las señales de control de la consola de Windows
Publicado en C/C++, Windows el 15 de April, 2009 por Fran.En Windows existen cinco señales de la consola que se emiten cuando se producen varios eventos, todos relacionados con el fin de la aplicación (Ctrl+C o Ctrl+Break), con el cierre de la consola (más llanamente, es el cierre de la ventana del cmd.exe) o con el fin de la sesión en Windows (el cierre de una sesión de usuario o el apagado del sistema).
Windows emite estas señales a las aplicaciones correspondientes para que puedan manejarlas y terminar de una forma adecuada, por ejemplo: realizando las operaciones necesarias para no dejar archivos en algún estado catastrófico perdiendo la información de estos.
Manejando las señales
Para manejar estas señales las aplicaciones disponen de una lista de manejadores, en la que en principio sólo hay una función que termina la ejecución del proceso. Para añadir/borrar un manejador a la lista se dispone de la función SetConsoleCtrlHandler:
BOOL WINAPI SetConsoleCtrlHandler (PHANDLER_ROUTINE HandlerRoutine, BOOL Add);
Donde los parámetros son:
- HandlerRoutine: Es un puntero a la función que manejará las señales recibidas. Tendrá la forma:
BOOL WINAPI CtrlHandler (DWORD CtrlType)
- Add: Si su valor es TRUE indica que la función se añadirá a la lista de manejadores de las señales, en cambio si es FALSE indica que la función se borrará de la lista de manejadores.
La función del manejador
Como se ha mencionado antes, la función del manejador tiene la forma:
BOOL CtrlHandler (DWORD CtrlType);
La función del manejador deberá tratar las señales que crea conveniente, utilizando el parámetro CtrlType que recibirá uno de los siguientes valores:
- CTRL_C_EVENT: Señal de Ctrl+C.
- CTRL_BREAK_EVENT: Señal de Ctrl+Break.
- CTRL_CLOSE_EVENT: Señal del cierre de la ventana de la consola.
- CTRL_LOGOFF_EVENT: Señal del cierre de la sesión.
- CTRL_SHUTDOWN_EVENT: Señal del apagado del sistema
Este manejador devolverá TRUE cuando haya tratado la señal, y FALSE cuando no la haya tratado, de modo que pasará a ejecutar el siguiente manejador.
Ejemplo
Como todo se entiende mejor con un ejemplo, aquí os dejo el ejemplo de la MSDN sobre registrar un manejador de señales de control de la consola:
#include <windows.h>
#include <stdio.h>
BOOL WINAPI CtrlHandler (DWORD CtrlType) {
switch (CtrlType) {
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
printf ("Ctrl-C event\n\n");
Beep (750, 300);
return TRUE;
// CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
printf ("Ctrl-Close event\n\n");
Beep (600, 200);
return TRUE;
// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
printf ("Ctrl-Break event\n\n");
Beep (900, 200);
return FALSE;
case CTRL_LOGOFF_EVENT:
printf ("Ctrl-Logoff event\n\n");
Beep (1000, 200);
return FALSE;
case CTRL_SHUTDOWN_EVENT:
printf ("Ctrl-Shutdown event\n\n");
Beep (750, 500);
return FALSE;
default:
return FALSE;
}
}
int main (int argc, char *argv[]) {
BOOL added;
added = SetConsoleCtrlHandler ((PHANDLER_ROUTINE) CtrlHandler,
TRUE);
if (added) {
printf ("\nThe Control Handler is installed.\n");
printf ("\n -- Now try pressing Ctrl+C or Ctrl+Break, or");
printf ("\n try logging off or closing the console...\n");
printf ("\n(...waiting in a loop for events...)\n\n");
while (1) {
Sleep (500);
}
} else
printf ("\nERROR: Could not set control handler");
return 0;
}
Bonito este nuevo theme. El link a “¿Quiénes somos?” no churra.
# Hugo 29 de April, 2009
Muy buen aporte!
# Luciano 6 de June, 2009