简体   繁体   中英

Graceful exit when closing console window

I'm trying to make a graceful exit from a console app when the close button is hit.

bool done = false;

BOOL ctrl_handler(DWORD event)
{
    if (event == CTRL_CLOSE_EVENT) {
        done = true;
        return TRUE;
    }
    return FALSE;
}

int main()
{
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);

    while (!done)
        do_stuff();

    cleanup();
    cout << "bye";
}

My handler gets called properly but the main thread does not resume afterwards so the "bye" never happens. If I trap CTRL_C_EVENT instead and hit ^C in the console then the main thread is allowed to continue and exits gracefully. Is there some way to allow the main thread to exit gracefully on console close?

I've also tried using std::signal but it's the same. Works for ^C but not for window close.

Thanks Jonathan for the tip.

I saw that the handler is called on it's own thread. If the handler returns then the whole process is forced to exit so we need to give the main thread time to exit on its own.

bool done = false;

BOOL ctrl_handler(DWORD event)
{
    if (event == CTRL_CLOSE_EVENT) {
        done = true;
        Sleep(20000); // force exit after 20 seconds
        return TRUE;
    }
    return FALSE;
}

int main()
{
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)(ctrl_handler), TRUE);

    while (!done)
        do_stuff();

    cleanup();
    cout << "bye";
}

I think the better way would be to use:

if (event == CTRL_CLOSE_EVENT)
{
    ExitThread(0);
//  return TRUE; // warning C4702: unreachable code
}

The ExitThread will terminate the thread from which ctrl_handler gets called. This way ExitProcess will not be called, and your main thread will be able to perform all the needed cleanup.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM