关闭控制台时如何正确处理SIGBREAK?

时间:2014-08-12 13:52:25

标签: c++ windows process signals

我必须抓住点击控制台事件的关闭按钮,这对应于ctrl-break事件SIGBREAK,但显然存在一种不允许我做的超时什么程序似乎中止之后的任何超过5秒的时间(因此消息“正确结束!”将永远不会发生。)

如何强制系统执行关闭操作直到结束(或将超时延长到60秒)?

注意:使用相同的方法,我可以在SIGINT

之前使用fflush(stdout);成功处理CTRL + C事件(doStuffs();

注意2:我的代码基于以下答案:https://stackoverflow.com/a/181594/1529139

#include <csignal>

void foo(int sig)
{
    signal(sig, foo); // (reset for next signal)

    // do stuffs which takes aboutly 15 seconds
    doStuffs();

    cout << "Properly ended !";
}

int main(DWORD argc, LPWSTR *argv)
{
    signal(SIGBREAK, foo);
    myProgramLoop();
}

1 个答案:

答案 0 :(得分:1)

我认为超时是固定的,无法修改,请参阅API reference

  

如果进程在某个超时时间内没有响应,系统也会显示该对话框(CTRL_CLOSE_EVENT为5秒,CTRL_LOGOFF_EVENT和CTRL_SHUTDOWN_EVENT为20秒)。

     

进程可以使用SetProcessShutdownParameters函数来阻止显示CTRL_LOGOFF_EVENT和CTRL_SHUTDOWN_EVENT对话框。在这种情况下,系统只是在HandlerRoutine返回TRUE或超时时间结束时终止进程。

如何替代方法,只需禁用控制台窗口的关闭按钮:

GUITHREADINFO info = {0};
info.cbSize=sizeof(info);
GetGUIThreadInfo(NULL, &info);
HMENU hSysMenu = GetSystemMenu(info.hwndActive, FALSE);
EnableMenuItem(hSysMenu, SC_CLOSE, MF_GRAYED);

现在您可以通过Ctrl-C或其他键盘输入安全地处理关闭。