开发者

SetConsoleCtrlHandler routine issue

开发者 https://www.devze.com 2023-01-14 15:45 出处:网络
I\'m writting a console application in C++. I use SetConsoleCtr开发者_运维技巧lHandler to trap close and CTRL+C button. This allows for all my threads to stop and exit properly.

I'm writting a console application in C++.

I use SetConsoleCtr开发者_运维技巧lHandler to trap close and CTRL+C button. This allows for all my threads to stop and exit properly.

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.

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).

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.

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?


It looks like you can no longer ignore close requests on Windows 7.

You do get 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.

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.)


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".


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).

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


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.


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:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消