0

我試圖在C++/CLI應用程序中捕獲任何和所有異常,以便我可以記錄並記錄它們(包括堆棧跟蹤)。到目前爲止,我有一些代碼,看起來前途無量:捕獲用於登錄C++ CLI應用程序的異常

[STAThreadAttribute] 
int main(array<System::String ^> ^args) 
{ 
    // Enabling Windows XP visual effects before any controls are created 
    Application::EnableVisualStyles(); 
    Application::SetCompatibleTextRenderingDefault(false); 

    // Create the main window and run it 
    try 
    { 
     Application::Run(gcnew MainForm()); 
    } 
    catch(System::Exception^ e) 
    { 
     String^ message = gcnew String(""); 
     System::Exception^ exceptionRecursor = e; 

     message = "ERROR: Uncaught exception encountered!\n\n"; 
     while(exceptionRecursor) 
     { 
      message += exceptionRecursor->Source+"\n\t"; 
      message += exceptionRecursor->Message+"\n\t"; 
      message += exceptionRecursor->StackTrace+"\n\n"; 
      exceptionRecursor = exceptionRecursor->InnerException; 
     } 
     MessageBox::Show(message); 
    } 

    return 0; 
} 

...但不是disaplying一個對話框,我收拾了錯誤,我得到別的東西:

An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll 

Additional information: Exception has been thrown by the target of an invocation. 

這是因爲Run命令試圖以某種方式處理異常?我需要在MainForm的某個地方處理東西嗎? ...還是有其他(更好)的方式去做這件事。

暫時忘記錯誤的來源(我在開發週期中,仍然在調試中),能夠捕獲這些錯誤併產生一個可以保留在代碼中的整潔的小堆棧跟蹤會很好直到部署,並讓用戶知道什麼時候出現問題。最終,我會將錯誤報告包裝成可通過網絡報告的內容。

回答

0

我發現(使用Application::ThreadException)的解決方案:

// Creates a class to throw the error. 
public: 
    ref class ErrorHandler: public System::Windows::Forms::Form 
    { 
     // Inserts the code to create a form with a button. 

     // Programs the button to throw an exception when clicked. 
    private: 
     void button1_Click(Object^ /*sender*/, System::EventArgs^ /*e*/) 
     { 
     throw gcnew ArgumentException("The parameter was invalid"); 
     } 

    public: 
     static void Main() 
     { 
     // Creates an instance of the methods that will handle the exception. 
     CustomExceptionHandler^eh = gcnew CustomExceptionHandler; 

     // Adds the event handler to to the event. 
     Application::ThreadException += gcnew ThreadExceptionEventHandler(eh, &Form1::CustomExceptionHandler::OnThreadException); 

     // Runs the application. 
     Application::Run(gcnew ErrorHandler); 
     } 
    }; 

// Creates a class to handle the exception event. 
internal: 
    ref class CustomExceptionHandler 
    { 
     // Handles the exception event. 
    public: 
     void OnThreadException(Object^ /*sender*/, ThreadExceptionEventArgs^ t) 
     { 
     System::Windows::Forms::DialogResult result = ::DialogResult::Cancel; 
     try 
     { 
      result = this->ShowThreadExceptionDialog(t->Exception); 
     } 
     catch (Exception^) 
     { 
      try 
      { 
       MessageBox::Show("Fatal Error", "Fatal Error", MessageBoxButtons::AbortRetryIgnore, MessageBoxIcon::Stop); 
      } 
      finally 
      { 
       Application::Exit(); 
      } 
     } 

     // Exits the program when the user clicks Abort. 
     if (result == ::DialogResult::Abort) 
     { 
      Application::Exit(); 
     } 
     } 

     // Creates the error message and displays it. 
    private: 
     System::Windows::Forms::DialogResult ShowThreadExceptionDialog(Exception^ e) 
     { 
     String^ errorMsg = "An error occurred please contact the adminstrator with the following information:\n\n"; 
     errorMsg = String::Concat(errorMsg, e->Message, "\n\nStack Trace:\n", e->StackTrace); 
     return MessageBox::Show(errorMsg, "Application Error", MessageBoxButtons::AbortRetryIgnore, MessageBoxIcon::Stop); 
     } 
    }; 
0

如果反射發生在另一個線程中,則包裝程序不會捕獲它失敗。

+0

難道這就是應用::運行用途?文檔[http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx]沒有提到有關新線程的任何內容? – 2009-07-15 11:19:08

相關問題