Перехват Ctrl+C и Ctrl+Break в консольных программах
Перехват Ctrl+C и Ctrl+Break в консольных программах
В отличие от оконных приложений, у консольных программ не так много возможностей по обработке разных нештатных ситуаций, например, внепланового завершения работы. Это может быть нажатие комбинаций Ctrl+С, Ctrl+Break или закрытие окна консоли. Правильно написанное приложение должно уметь обрабатывать подобные ситуации и корректно завершать работу, то есть успеть сохранить какие-то промежуточные данные, освободить занятые ресурсы или уведомить пользователя, что его действия контрпродуктивны.
В WinAPI есть замечательная функция SetConsoleCtrlHandler, с помощью которой консольное приложение может не только узнавать о попытках его принудительного завершения, но даже блокировать нажатия Ctrl+С и Ctrl+Break. Работа с этой функцией очень простая: при старте консольное приложение с ее помощью устанавливает свой обработчик событий, а при завершении с ее же помощью убирает его:
Code (Assembler) : Убрать нумерацию
- ; Установить обработчик событий
- invoke SetConsoleCtrlHandler,HandlerRoutine,TRUE
- ...
- ...
- ...
- ; Удалить обработчик событий
- invoke SetConsoleCtrlHandler,NULL,FALSE
Code (Assembler) : Убрать нумерацию
- proc HandlerRoutine dwCtrlType:DWORD
- ; Нажата комбинация Ctrl+C
- cmp [dwCtrlType],CTRL_C_EVENT
- jne @f
- ...
- ...
- jmp .loc_handle
- @@:
- ; Нажата комбинация Ctrl+Break
- cmp [dwCtrlType],CTRL_BREAK_EVENT
- jne @f
- ...
- ...
- jmp .loc_handle
- @@:
- ; Окно консоли закрывается
- cmp [dwCtrlType],CTRL_CLOSE_EVENT
- jne .loc_ret
- ...
- ...
- .loc_handle:
- ; Функция обработала событие
- mov eax,TRUE
- ret
- .loc_ret:
- ; Пропустить событие дальше
- mov eax,FALSE
- ret
- endp
В приложении пример программы с исходным текстом, которая на время работы перехватывает и блокирует комбинации Ctrl+C и Ctrl+Break, а также обрабатывает принудительное закрытие консоли.
Просмотров: 3543 | Комментариев: 3
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Добавить комментарий
Заполните форму для добавления комментария
Что в вольном переводе означает: если консольная программа, запущенная на Win7 и выше, импортирует напрямую, или каким-либо иным образом в процессе работы задействует библиотеки gdi32.dll или user32.dll, то события CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT в обработчик передаваться не будут. Для этого надо создавать невидимое окно и ставить перехват завершения работы на него.
А еще гуру М.Руссинович и Д.Соломон в своей книге "Внутреннее устройство Windows XP" пишут следующее:
Сказанное, опять же, относится только к Windows XP. Так что пляски с бубном по этим двум событиям вообще запредельные, и просто взять и обработать их в обычном приложении не получится.