2015-06-15 51 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,則調用下一個註冊的Handler,直到返回「TRUE」或達到默認的「Handler」,在任何一種情況下,該過程都會終止。你必須考慮到'Handler'是在它自己的線程環境中調用的,所以確保它的代碼是線程安全的。 –

+0

我想在很多情況下,它對於處理程序例程來說是最簡單的,用於設置一個標誌,然後在主線程終止該進程之前一直睡眠。 –

相關問題