windows SetConsoleCtrlHandler 例程问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3640633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SetConsoleCtrlHandler routine issue
提问by Jeremy
I'm writting a console application in C++.
我正在用 C++ 编写一个控制台应用程序。
I use SetConsoleCtrlHandler to trap close and CTRL+C button. This allows for all my threads to stop and exit properly.
我使用 SetConsoleCtrlHandler 来捕获关闭和 CTRL+C 按钮。这允许我的所有线程正确停止和退出。
One of the thread performs some saving that require some time to complete and I have some code to wait in the console crtl handle routine. MSDN specify that a box should pop up after 5 seconds for CTRL_CLOSE_EVENT, but instead my process exits.
其中一个线程执行一些需要一些时间才能完成的保存,我有一些代码要在控制台 crtl 处理例程中等待。MSDN 指定 CTRL_CLOSE_EVENT 应在 5 秒后弹出一个框,但我的进程退出。
This is annoying for debugging console application too as the process exits before you can step through and I don't know what may be the problem (I have Windows 7 64bits).
这对于调试控制台应用程序也很烦人,因为进程在您可以单步执行之前退出,我不知道可能是什么问题(我有 Windows 7 64 位)。
Also, strangely if my routine returns TRUE (to simply disable the close action), it still closes the application. The routine does get called, so the SetConsoleCtrlHandler was successful installed.
此外,奇怪的是,如果我的例程返回 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;
}
Any ideas?
有任何想法吗?
采纳答案by Ren Hoek
It looks like you can no longer ignore close requests on Windows 7.
看起来您不能再忽略 Windows 7 上的关闭请求。
You doget the CTRL_CLOSE_EVENT event though, and from that moment on, you get 10 seconds to do whatever you need to do before it auto-closes. So you can either do whatever work you need to do in the handler or set a global flag.
不过,您确实会收到 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;
Fun fact: While the code in your CTRL_CLOSE_EVENT event runs, the main program keeps on running. So you'll be able to check for the flag and do a 'close_flag = 2;' somewhere. But remember, you only have 10 seconds. (So keep in mind you don't want to hang up your main program flow waiting on keyboard input for example.)
有趣的事实:当 CTRL_CLOSE_EVENT 事件中的代码运行时,主程序继续运行。因此,您将能够检查标志并执行“close_flag = 2;” 某处。但请记住,您只有 10 秒钟。(因此请记住,例如,您不想挂断主程序流程以等待键盘输入。)
回答by C-cubed
Xavier's comment is slightly wrong. Windows 7 allows your code in the event handler ~10 seconds. If you haven't exited the event handler in 10 seconds you are terminated. If you exit the event handler you are terminated immediately. Returning TRUE does not post a dialog. It just exits.
泽维尔的评论有点错误。Windows 7 允许您在事件处理程序中使用代码约 10 秒。如果您在 10 秒内没有退出事件处理程序,您将被终止。如果您退出事件处理程序,您将立即终止。返回 TRUE 不会发布对话框。它只是退出。
回答by Matlo
There is no need to wait for any flag from the main thread, the handler terminates as soon as the main thread exits (or after 10s).
不需要等待来自主线程的任何标志,一旦主线程退出(或 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;
}
回答by Ana Betts
I suspect that this is by-design on Windows 7 - if the user wants to quit your application, you're not allowed to tell him "No".
我怀疑这是 Windows 7 上的设计 - 如果用户想退出您的应用程序,则不允许告诉他“不”。
回答by Billy ONeal
You're making this more complicated than it needs to be. I don't know exactly why your app is closing, but SetConsoleCtrlHandler(NULL, TRUE)
should do what you want:
你让这比它需要的更复杂。我不知道您的应用程序关闭的确切原因,但SetConsoleCtrlHandler(NULL, TRUE)
应该做您想做的事:
http://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms686016(VS.85).aspx
If the HandlerRoutine parameter is NULL, a TRUE value causes the calling process to ignore CTRL+C input, and a FALSE value restores normal processing of CTRL+C input.
如果 HandlerRoutine 参数为 NULL,则 TRUE 值会导致调用进程忽略 CTRL+C 输入,而 FALSE 值会恢复 CTRL+C 输入的正常处理。