SetConsoleCtrlHandler例程问题

我正在用C ++写一个控制台应用程序

我使用SetConsoleCtrlHandler来捕捉closures和CTRL + Cbutton。 这允许我的所有线程停止并正常退出。

其中一个线程执行一些保存,需要一些时间来完成,我有一些代码在控制台crtl处理例程中等待。 MSDN指定CTRL_CLOSE_EVENT 5秒后popup一个框,但是我的进程退出。

这是烦人的debugging控制台应用程序,因为过程退出之前,你可以通过,我不知道可能是什么问题(我有Windows 7 64位)。

此外,奇怪的是,如果我的例程返回TRUE(简单地禁用closures操作),它仍然closures应用程序。 该例程确实被调用,所以SetConsoleCtrlHandler被成功安装。

例如:

BOOL WINAPI ConsoleHandlerRoutine(DWORD dwCtrlType) { if (dwCtrlType == CTRL_CLOSE_EVENT) { return TRUE; } return FALSE; } int _tmain(int argc, _TCHAR* argv[]) { BOOL ret = SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE); while (true) { Sleep(1000); } return 0; } 

有任何想法吗?

看起来您不能再忽略Windows 7上的关闭请求。

尽管如此,您仍然可以获得CTRL_CLOSE_EVENT事件,从那一刻起,您可以在10秒钟内完成自动关闭之前所需的任何操作。 所以你可以做任何你需要在处理程序中做的工作或设置一个全局标志。

 case CTRL_CLOSE_EVENT: // CTRL-CLOSE: confirm that the user wants to exit. close_flag = 1; while(close_flag != 2) Sleep(100); return TRUE; 

有趣的事实:当您的CTRL_CLOSE_EVENT事件中的代码运行时,主程序继续运行。 所以你可以检查标志并做一个'close_flag = 2' 某处。 但请记住,你只有10秒。 (所以请记住,你不想挂起等待键盘输入的主程序流。)

我怀疑这是在Windows 7上的设计 – 如果用户想要退出你的应用程序,你不能告诉他“不”。

没有必要等待主线程中的任何标志,只要主线程退出(或10秒之后),处理程序就会终止。

 BOOL WINAPI ConsoleHandler(DWORD dwType) { switch(dwType) { case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: set_done();//signal the main thread to terminate //Returning would make the process exit! //We just make the handler sleep until the main thread exits, //or until the maximum execution time for this handler is reached. Sleep(10000); return TRUE; default: break; } return FALSE; } 

泽维尔的评论有些不对。 Windows 7允许您的代码在事件处理程序〜10秒。 如果您在10秒内没有退出事件处理程序,则会被终止。 如果您退出事件处理程序,则立即终止。 返回TRUE不会发布对话框。 它只是退出。

你正在使这个比需要更复杂。 我不知道为什么你的应用程序正在关闭,但SetConsoleCtrlHandler(NULL, TRUE)应该做你想要的:

http://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx

如果HandlerRoutine参数为NULL,则TRUE值将导致调用进程忽略CTRL + C输入,而FALSE值将恢复CTRL + C输入的正常处理。