Función SetConsoleCtrlHandler
Agrega o quita una función HandlerRoutine definida por la aplicación de la lista de funciones de controlador para el proceso de llamada.
Si no se especifica ninguna función de controlador, la función establece un atributo heredable que determina si el proceso de llamada ignora las señales de CTRL+C.
BOOL WINAPI SetConsoleCtrlHandler(
_In_opt_ PHANDLER_ROUTINE HandlerRoutine,
_In_ BOOL Add
);
HandlerRoutine [in, opcional]
Puntero a la función HandlerRoutine definida por la aplicación que se va a agregar o quitar. Este parámetro puede ser NULL.
Add [in]
Si este parámetro es TRUE, se agrega el controlador; si es FALSE, se quita el controlador.
Si el parámetro HandlerRoutine es NULL, un valor TRUE provoca que el proceso de llamada ignore la entrada CTRL+C. Un valor FALSE restaura el procesamiento normal de la entrada CTRL+C. Los procesos secundarios heredan este atributo de ignorar o procesar CTRL+C.
Si la función se realiza correctamente, el valor devuelto es distinto de cero.
Si la función no se realiza correctamente, el valor devuelto es cero. Para obtener información de error extendida, llame a GetLastError.
Esta función proporciona una notificación similar a la aplicación de consola y los servicios que WM_QUERYENDSESSION proporciona para aplicaciones gráficas con un bombeo de mensajes. También puede usar esta función desde una aplicación gráfica, pero no hay ninguna garantía de que llegue antes de la notificación de WM_QUERYENDSESSION.
Cada proceso de consola tiene su propia lista de funciones HandlerRoutine definidas por la aplicación que controlan las señales de CTRL+C y CTRL+BREAK. Las funciones de controlador también controlan las señales generadas por el sistema cuando el usuario cierra la consola, cierra sesión o apaga el sistema. Inicialmente, la lista de controladores para cada proceso solo contiene una función de controlador predeterminada que llama a la función ExitProcess. Un proceso de consola agrega o quita funciones de controlador adicionales mediante una llamada a la función SetConsoleCtrlHandler, que no afecta a la lista de funciones de controlador para otros procesos. Cuando un proceso de consola recibe alguna de las señales de control, se llama a sus funciones de controlador en función del último registro y la primera llamada, hasta que uno de los controladores devuelve TRUE
. Si ninguno de los controladores devuelve TRUE
, se llama al controlador predeterminado.
Al llamar a AttachConsole, AllocConsole o FreeConsole, la tabla de identificadores de control en el proceso de cliente se restablecerá a su estado inicial. Los controladores se deben registrar de nuevo cuando cambia la sesión de la consola adjunta.
En el caso de los procesos de consola, normalmente las combinaciones de teclas CTRL+C y CTRL+INTERRUMPIR se tratan como señales (CTRL_C_EVENT y CTRL_BREAK_EVENT). Cuando una ventana de consola con el foco de teclado recibe CTRL+C o CTRL+BREAK, normalmente la señal se pasa a todos los procesos que comparten esa consola.
CTRL+BREAK se trata siempre como una señal, pero un comportamiento típico de CTRL+C se puede cambiar de tres maneras que impidan que se llame a las funciones del controlador:
- La función SetConsoleMode puede deshabilitar el modo ENABLE_PROCESSED_INPUT para el búfer de entrada de una consola, por lo que CTRL+C se indica como entrada del teclado en lugar de como una señal.
- La llamada a SetConsoleCtrlHandler con los argumentos NULL y TRUE hace que el proceso de llamada ignore las señales de CTRL+C. Los procesos secundarios heredan este atributo, pero puede habilitarse o deshabilitarse en cualquier proceso sin que ello afecte a los procesos existentes.
- Si se está depurando un proceso de consola y no se han deshabilitado las señales de CTRL+C, el sistema genera una excepción DBG_CONTROL_C. Esta excepción solo se produce en beneficio del depurador y una aplicación nunca debe utilizar un controlador de excepciones para tratarla. Si el depurador controla la excepción, una aplicación no tendrá en cuenta CTRL+C, con una excepción: se terminarán las esperas que generan alertas. Si el depurador pasa la excepción como no controlada, CTRL+C se pasa al proceso de consola y se trata como una señal, como se explicó anteriormente.
Un proceso de consola puede usar la función GenerateConsoleCtrlEvent para enviar una señal de CTRL+C o CTRL+BREAK a un grupo de procesos de consola.
El sistema genera señales de CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT y CTRL_SHUTDOWN_EVENT cuando el usuario cierra la consola, cierra sesión o apaga el sistema para que el proceso tenga una oportunidad de limpiarse antes de que finalice. Es posible que las funciones de consola o cualquier función en tiempo de ejecución de C que llame a funciones de consola no funcionen de forma confiable durante el procesamiento de cualquiera de las tres señales mencionadas anteriormente. El motivo es que es posible que se haya llamado a algunas o todas las rutinas de limpieza internas de la consola antes de ejecutar el controlador de la señal de proceso.
Windows 7, Windows 8, Windows 8.1 y Windows 10:
Si una aplicación de consola carga la biblioteca gdi32.dll o user32.dll, no se llama a la función HandlerRoutine que se especifica cuando se llama a SetConsoleCtrlHandler para los eventos CTRL_LOGOFF_EVENT y CTRL_SHUTDOWN_EVENT. El sistema operativo reconoce los procesos que cargan gdi32.dll o user32.dll como aplicaciones Windows en lugar de aplicaciones de consola. Este comportamiento también se produce en las aplicaciones de consola que no llaman directamente a las funciones de gdi32.dll o user32.dll, sino que llaman a funciones como funciones de Shell que, a su vez, llaman a funciones de gdi32.dll o user32.dll.
Para recibir eventos cuando un usuario cierra sesión o el dispositivo se apaga en estas circunstancias, cree una ventana oculta en la aplicación de consola y, a continuación, controle los mensajes de la ventana WM_QUERYENDSESSION y WM_ENDSESSION que recibe la ventana oculta. Para crear una ventana oculta, llame al método CreateWindowEx con el parámetro dwExStyle establecido en 0. Un ejemplo de esto se incluye con el ejemplo de controlador básico vinculado a continuación.
Por ejemplo, consulte Registro de una función de identificador de control.
Cliente mínimo compatible | Windows 2000 Professional [solo aplicaciones de escritorio] |
Servidor mínimo compatible | Windows 2000 Server [solo aplicaciones de escritorio] |
Encabezado | ConsoleApi.h (a través de WinCon.h, incluido Windows.h) |
Biblioteca | Kernel32.lib |
Archivo DLL | Kernel32.dll |
Nombres Unicode y ANSI |