2010-06-22 134 views
4

如果我的應用程序崩潰,我使用ExceptionFilter趕上大跌,進行一些最後的動作,然後顯示一個消息框應用程序崩潰的用戶。的MessageBox與超時或從另一個線程關閉一個MessageBox

由於應用程序已經墜毀,機上有沒有什麼我可以(或我不敢)做,因爲如果我做的太多,執行的代碼可能會再次訪問損壞的內存和崩潰。 我目前不能做的一些事情(或者我不敢做)是關閉網絡連接,Oracle數據庫會話......

問題是,如果一個應用程序崩潰,並且用戶是在MessageBox處於打開狀態時進行午餐時,由於打開數據庫會話,可能會阻止其他用戶。因此我想要:

  • 可能是帶有超時的MessageBox。問題是,你不能用標準的MessageBox Win32 API函數做到這一點,我不想做具體的對話吧(因爲我希望儘量減少撞車後執行的邏輯)
  • 或者可能性關閉另一個線程的MessageBox(另一個線程可以提供超時邏輯)。

我是否忽略了Win32 API中的某些內容,並且有可能產生超時的MessageBox?

或什麼是從另一個線程關閉打開的消息框的正確方法(如何獲取MessageBox的手柄,怎麼關閉它,...)?

回答

1

這不合理的線程。

最好的解決方案是使用模式對話框,註冊一個自動關閉定時器。

+0

我想要寫相同的建議:建立針對DialogBox'的'一個新的對話框,創建'WM_INITDIALOG'的'內SetTimer'一個計時器,並關閉對話框在'WM_TIMER'中。 – Oleg 2010-06-22 08:30:43

3

你應該問自己,爲什麼你想要一個消息箱。當沒有人坐在電腦前時沒有看到消息框時,爲什麼當用戶的程序消失時用戶看不到消息?

如果你真的想要的話,我認爲最簡單的辦法是產卵顯示郵件的新工藝。它可以運行,只要它不會影響你的崩潰程序。

1

剛剛將事件記錄到本地文件(並記錄內存轉儲或您可能需要以後調試的任何信息)呢?

你可以關閉你的應用程序,關閉網絡連接並做你的家務。

一旦應用程序再次啓動,可以讓您的用戶(根據本地文件信息),去年在執行過程中的應用程序崩潰。

0

我會運行您的原始代碼從一個包裝的應用程序,執行一個CreateProcess,然後在進程句柄上MsgWaitForMultipleObjects(大多數進程啓動代碼示例使用WaitForSingleObject,但你需要防範消息死鎖情況)。然後您的觀察過程可以檢測到產生的過程失敗,彈出自己的超時對話框,並退出用戶響應或超時。

我認爲這是最乾淨的解決方案,它可以防止不穩定的程序執行任何代碼。

5

雖然我同意產卵一個新的程序來顯示一個遺忘而忽略的對話框可能是最好的,但FWIW實際上有一個可以從user32上面導出的XP &上的可超時的消息框功能; MessageBoxTimeout(用於像WShell.Popup()之類的東西)

0

Win32 MessageBox實際上是一個對話框,帶有對話框消息泵。因此你可以依靠標準的Win32定時器消息(WM_TIMER)。發送一個到你自己的窗口,當你得到它時,通過發送一個WM_COMMAND/BN_CLICKED消息到ID_OK按鈕來消除MessageBox。

消息框,因爲它是一個對話框,將類「#32770」。由於它是唯一一個可以打開的對話框,因此在您的子窗口中很容易找到。

1

快速複製/粘貼的解決方案:

int DU_MessageBoxTimeout(HWND hWnd, const WCHAR* sText, const WCHAR* sCaption, UINT uType, DWORD dwMilliseconds) 
{ 
    // Displays a message box, and dismisses it after the specified timeout. 
    typedef int(__stdcall *MSGBOXWAPI)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds); 

    int iResult; 

    HMODULE hUser32 = LoadLibraryA("user32.dll"); 
    if (hUser32) 
    { 
     auto MessageBoxTimeoutW = (MSGBOXWAPI)GetProcAddress(hUser32, "MessageBoxTimeoutW"); 

     iResult = MessageBoxTimeoutW(hWnd, sText, sCaption, uType, 0, dwMilliseconds); 

     FreeLibrary(hUser32); 
    } 
    else 
     iResult = MessageBox(hWnd, sText, sCaption, uType);   // oups, fallback to the standard function! 

    return iResult; 
}