Search code examples
c++windows-7destructorterminate

Why is a destructor not called when I click the close button on the console?


I have a command line application on Windows 7. It consists mainly of an endless loop. When I click on the close button of the command-line console window, it seems to be killed instantly. However, I close an SQLite database connection in the destructor, and so I am afraid that the databse might be corrupted. Even if not, I'd like to be able to properly terminate my object (maybe by writing something to a file, logging, etc.).

Can I somehow make sure that my destructor is called? What exactly happens if I close the window? Is there a "softer" way to close a program?


Solution

  • A console application doesn't have a message loop where you're asked to quit however Windows gives you ability to register a function to receive some notifications you may need to handle. One of them is the closing notification.

    First of all declare a function that Windows will call for this purpose with prototype given by HandlerRoutine:

    BOOL WINAPI ConsoleHandlerRoutine(DWORD dwCtrlType) {
        if (CTRL_CLOSE_EVENT == dwCtrlType) {
            return TRUE;
        }
    
        return FALSE;
    }
    

    Now register that function, using SetControlCtrlHandler, before you start your loop:

    int main(int argc, char* argv[])
    {
        if (FALSE == SetConsoleCtrlHandler(ConsoleHandlerRoutine, TRUE)) {
            // Cannot register your handler? Check GetLastError()
        }
    
        while (true)
        {
            // This is your loop
        }
    
        return 0;
    }
    

    That's done. You can explicitly delete objects you want to dispose or simply set a flag that will break your infinite loop.

    Note that you will receive more events (Windows shutdown CTRL_SHUTDOWN_EVENT, user log-off CTRL_LOGOFF_EVENT, user break CTRL_C_EVENT, closing CTRL_CLOSE_EVENT), handle what you need/want.