Функция SetConsoleCtrlHandler
Добавляет определяемую приложением функцию HandlerRoutine в список функций обработчика для вызывающего процесса или удаляет ее из такого списка.
Если функция обработчика не указана, функция задает наследуемый атрибут, который определяет, игнорирует ли вызывающий процесс сигналы при нажатии клавиш CTRL+C.
Синтаксис
BOOL WINAPI SetConsoleCtrlHandler(
_In_opt_ PHANDLER_ROUTINE HandlerRoutine,
_In_ BOOL Add
);
Параметры
HandlerRoutine [ввод, необязательный]
Указатель на определяемую приложением функцию HandlerRoutine, которая будет добавлена или удалена. Этот параметр может принимать значение NULL.
Add [ввод]
Если этот параметр имеет значение TRUE, обработчик добавляется; если FALSE — обработчик удаляется.
Если параметр HandlerRoutine имеет значение NULL, значение TRUE приводит к тому, что вызывающий процесс игнорирует нажатие клавиш CTRL+C, а значение FALSE восстанавливает нормальную обработку нажатия CTRL+C. Этот атрибут для игнорирования обработки CTRL+C также наследуется дочерними процессами.
Возвращаемое значение
Если функция выполняется успешно, возвращается ненулевое значение.
Если функция выполняется неудачно, возвращается нулевое значение. Дополнительные сведения об ошибке можно получить, вызвав GetLastError.
Замечания
Эта функция предоставляет аналогичное уведомление для консольного приложения и служб, которое доступно в WM_QUERYENDSESSION для графических приложений с конвейером сообщений. Вы также можете использовать эту функцию из графического приложения, но при этом не гарантируется ее доставка перед получением уведомления от WM_QUERYENDSESSION.
Каждый процесс консоли имеет собственный список определяемых приложением функций HandlerRoutine, которые обрабатывают сигналы при нажатии клавиш CTRL+C и CTRL+BREAK. Функции обработчика также обрабатывают сигналы, генерируемые системой, когда пользователь закрывает консоль, выходит из системы или завершает ее работу. Изначально список обработчиков для каждого процесса содержит только стандартную функцию обработчика, которая вызывает функцию ExitProcess. Процесс консоли добавляет или удаляет дополнительные функции обработчика, вызывая функцию SetConsoleCtrlHandler, которая не влияет на список функций обработчика для других процессов. Если процесс консоли получает любые управляющие сигналы, его функции обработчика вызываются по принципу "зарегистрирован последним — вызван первым", пока один из обработчиков не вернет значение TRUE
. Если ни один из обработчиков не возвращает значение TRUE
, вызывается обработчик по умолчанию.
Вызов AttachConsole, AllocConsole или FreeConsole приведет к сбросу таблицы обработчиков элементов управления в клиентском процессе до исходного состояния. Обработчики необходимо повторно зарегистрировать при изменении сеанса присоединенной консоли.
Для процессов консоли ввод CTRL+C и CTRL+BREAK обычно обрабатывается как сигналы (CTRL_C_EVENT и CTRL_BREAK_EVENT). Если окно консоли с фокусом для ввода текста с клавиатуры получает нажатие клавиш CTRL+C или CTRL+BREAK, сигнал обычно передается всем процессам, использующим эту консоль.
Нажатие клавиш CTRL+BREAK всегда обрабатывается как сигнал, но типичное поведение CTRL+C можно изменить тремя способами, чтобы предотвратить вызов функций обработчика:
- Функция SetConsoleMode может отключить режим ENABLE_PROCESSED_INPUT для входного буфера консоли, поэтому CTRL+C регистрируется как ввод с клавиатуры, а не как сигнал.
- Вызов функции SetConsoleCtrlHandler с аргументами NULL и TRUE приводит к тому, что вызывающий процесс игнорирует сигналы нажатия CTRL+C. Этот атрибут наследуется дочерними процессами, но его можно включить или отключить в любом процессе, не затрагивая имеющиеся процессы.
- Если выполняется отладка процесса консоли и сигналы ввода CTRL+C не отключены, система выдаст исключение DBG_CONTROL_C. Это исключение отображается только для того, чтобы упростить отладку — приложению не нужно использовать обработчик исключений для его обработки. Если отладчик обрабатывает исключение, приложение проигнорирует нажатие клавиш CTRL+C (с одним исключением: ожидания с возможностью оповещения будут завершены). Если отладчик передает исключение необработанным, нажатие клавиш CTRL+C передается в процесс консоли и обрабатывается как сигнал, как было описано ранее.
Процесс консоли может использовать функцию GenerateConsoleCtrlEvent для отправки сигнала нажатия CTRL+C или CTRL+BREAK в группу процессов консоли.
Система выводит сигналы CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT, если пользователь закрывает консоль, выходит из системы или завершает работу системы таким образом, чтобы процесс мог предварительно очистить данные в памяти. Функции консоли или любые функции среды выполнения C, которые вызывают функции консоли, могут работать нестабильно в процессе обработки любого из упомянутых выше трех сигналов. Причина заключается в том, что некоторые из внутренних подпрограмм очистки консоли могут вызываться перед выполнением обработчика сигналов процесса.
В Windows 7, Windows 8, Windows 8.1 и Windows 10:
Если консольное приложение загружает библиотеку gdi32.dll или user32.dll, функция HandlerRoutine, указанная вами при вызове SetConsoleCtrlHandler, не вызывается для событий CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT. Операционная система обрабатывает процессы, которые загружают библиотеку gdi32.dll или user32.dll, как приложения Windows, а не как консольные приложения. Такое поведение также характерно для консольных приложений, которые не вызывают функции непосредственно в gdi32.dll или user32.dll, но вызывают, например, функции оболочки, которые в свою очередь вызывают функции в gdi32.dll или user32.dll.
Чтобы получать события, когда пользователь выходит из системы или устройство завершает работу в таких условиях, создайте скрытое окно в консольном приложении, а затем обеспечьте обработку сообщений окна WM_QUERYENDSESSION и WM_ENDSESSION, которые получает скрытое окно. Вы можете создать скрытое окно, вызвав метод CreateWindowEx с параметром dwExStyle, для которого задано значение 0. См. пример базового дескриптора ниже.
Примеры
Пример см. в статье Регистрация функции обработчика команд управления.
Requirements
Минимальная версия клиента | Windows 2000 Professional [только классические приложения] |
Минимальная версия сервера | Windows 2000 Server [только классические приложения] |
Верхний колонтитул | ConsoleApi.h (через WinCon.h, включая Windows.h) |
Библиотека | Kernel32.lib |
DLL-библиотеки | Kernel32.dll |
Имена Юникода и ANSI |