2015-06-15 4 views
3

У меня есть приложение командной строки в Windows 7. Оно состоит в основном из бесконечного цикла. Когда я нажимаю кнопку закрытия окна командной строки, она, похоже, мгновенно убивается. Тем не менее, я закрываю соединение базы данных SQLite в деструкторе, поэтому я боюсь, что база данных может быть повреждена. Даже если это не так, я хотел бы иметь возможность правильно закончить свой объект (возможно, путем написания чего-то файла, регистрации и т. Д.).Почему деструктор не вызван, когда я нажимаю кнопку закрытия на консоли?

Могу ли я как-то убедиться, что мой деструктор называется? Что именно происходит, если я закрою окно? Есть ли более «мягкий» способ закрыть программу?

ответ

2

консольное приложение не имеет цикла обработки сообщений, где вы попросили выйти, однако для Windows дает возможность регистрировать функцию, чтобы получить некоторыхуведомления вам может понадобиться для работы. Одним из них является уведомление .

Прежде всего объявить функцию, которая для Windows будет вызывать для этой цели с прототипом заданной HandlerRoutine:

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

    return FALSE; 
} 

Теперь зарегистрировать эту функцию, используя SetControlCtrlHandler, прежде чем начать свой цикл:

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

Все готово. Вы можете явно удалять объекты, которые хотите разместить, или просто установить флаг, который разрушит ваш бесконечный цикл.

Обратите внимание, что вы получите больше событий (Windows выключение CTRL_SHUTDOWN_EVENT, логарифмически от пользователя CTRL_LOGOFF_EVENT, перерыв пользователь CTRL_C_EVENT, закрывая CTRL_CLOSE_EVENT), обрабатывать то, что вам нужно/хочу.

+0

... на самом деле я не уверен, что вы можете установить флаг, не нужно ли выполнять очистку перед выходом из консоли ConsoleHandlerRoutine? –

+1

@HarryJohnston: Да. Если 'Handler' возвращает TRUE, процесс немедленно прекращается. Если он возвращает FALSE, вызывается следующий зарегистрированный «обработчик» и т. Д., Пока не будет достигнуто значение «TRUE» или «Handler» по умолчанию, в любом случае процесс завершается. И вы должны принять во внимание, что 'Handler' вызывается в контексте его собственного потока, поэтому убедитесь, что его код является потокобезопасным. –

+0

Я предполагаю, что во многих случаях для прогона обработчика проще всего установить флаг, а затем просто спать до тех пор, пока основной поток не завершит процесс. –