SetConsoleCtrlHandler函数从调用进程的处理函数列表中添加或删除应用程序定义的HandlerRoutine函数。如果没有指定处理程序函数,则该函数设置一个可继承属性,该属性确定调用进程是否忽略CTRL + C信号。
BOOL SetConsoleCtrlHandler(
PHANDLER_ROUTINE 【HandlerRoutine】, | //处理函数的地址 |
BOOL 【加】 | //处理程序添加或删除 |
); |
参数
【HandlerRoutine】
指向应用程序定义的HandlerRoutine功能添加或删除。此参数可以为NULL。
【加】
指定是否从处理程序列表中添加或删除【HandlerRoutine】参数指向的函数。如果此参数为TRUE,则添加处理程序;如果为FALSE,则处理程序将被删除。
如果【HandlerRoutine】参数为NULL,则TRUE值将导致调用进程忽略CTRL + C输入,而FALSE值恢复CTRL + C输入的正常处理。忽略或处理CTRL + C的属性由子进程继承。
返回值
如果函数成功,返回值不为零。
如果函数失败,返回值为零。要获取扩展错误信息,请调用GetLastError.
备注
每个控制台进程都有自己的应用程序定义的HandlerRoutine列表,处理CTRL + C和CTRL + BREAK信号。当用户关闭控制台,注销或关闭系统时,处理程序功能还处理由系统生成的信号。最初,每个进程的处理程序列表只包含调用ExitProcess函数的默认处理函数。控制台进程通过调用SetConsoleCtrlHandler函数来添加或删除其他处理函数,这不影响其他进程的处理函数列表。当控制台进程接收到任何控制信号时,其处理函数在最后注册的第一个基础上被调用,直到其中一个处理程序返回TRUE为止。如果处理程序没有返回TRUE,则调用默认处理程序。
对于控制台进程,CTRL + C和CTRL + BREAK组合键通常被视为信号(CTRL_C_EVENT和CTRL_C_BREAK_EVENT)。当具有键盘焦点的控制台窗口接收CTRL + C或CTRL + BREAK时,该信号通常传递给共享该控制台的所有进程。
CTRL + BREAK始终被视为信号,但是可以通过三种方式更改典型的CTRL + C行为,从而阻止处理函数被调用:
* SetConsoleMode功能可以禁用控制台输入缓冲区的ENABLE_PROCESSED_INPUT模式,因此CTRL + C被报告为键盘输入而不是信号。
*使用NULL和TRUE参数调用SetConsoleCtrlHandler会导致调用进程忽略CTRL + C信号。此属性由子进程继承,但可以由任何进程启用或禁用该属性,而不会影响现有进程。
*如果正在调试控制台进程并且CTRL + C信号未被禁用,内核将生成一个DBG_CONTROL_C异常。这个异常只是为了调试器的好处而引起的,应用程序永远不应该使用异常处理程序来处理它。如果调试器处理异常,应用程序将不会注意到CTRL + C,除了一个例外:alertable wait将终止。如果调试器在未处理的情况下传递异常,则CTRL + C将被传递到控制台进程并被视为信号,如前所述。
控制台进程可以使用GenerateConsoleCtrlEvent函数向控制台进程组发送CTRL + C或CTRL + BREAK信号。
当用户关闭控制台,注销或关闭系统时,系统会生成CTRL_CLOSE_EVENT,CTRL_LOGOFF_EVENT和CTRL_SHUTDOWN_EVENT信号,以便进程在终止之前有机会进行清理。调用控制台功能的控制台功能或任何C运行时功能在处理前面提到的三个信号中的任一个时可能无法可靠地工作。原因是在执行过程信号处理程序之前可能已经调用了部分或全部内部控制台清理程序。
也可以看看
ExitProcess, GenerateConsoleCtrlEvent, GetConsoleMode, HandlerRoutine, SetConsoleMode