SetConsoleCtrlHandler例程问题

时间:2010-09-04 02:19:58

标签: c++ windows console-application

我正在用C ++编写控制台应用程序。

我使用SetConsoleCtrlHandler来捕获close和CTRL + C按钮。这允许我的所有线程都能正常停止和退出。

其中一个线程执行一些需要一些时间才能完成的保存,并且我有一些代码要在控制台crtl句柄例程中等待。 MSDN指定CTRL_CLOSE_EVENT在5秒后弹出一个框,但我的进程退出。

这对于调试控制台应用程序也很烦人,因为在您可以单步执行之前进程退出并且我不知道可能是什么问题(我有Windows 7 64位)。

另外,奇怪的是如果我的例程返回TRUE(只是禁用关闭操作),它仍会关闭应用程序。该例程被调用,因此SetConsoleCtrlHandler已成功安装。

e.g:

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;
}

有什么想法吗?

5 个答案:

答案 0 :(得分:17)

您似乎无法再忽略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秒钟。 (所以请记住,你不想挂断等待键盘输入的主程序流程。)

答案 1 :(得分:3)

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

答案 2 :(得分:3)

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

答案 3 :(得分:3)

没有必要等待主线程中的任何标志,处理程序在主线程退出时(或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;
}

答案 4 :(得分:1)

你让它变得比它需要的更复杂。我不确切知道您的应用关闭的原因,但SetConsoleCtrlHandler(NULL, TRUE)应该做你想做的事情:

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

  

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