我试图捕获所有异常在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
地方吗? ...或者是那里要对此一些其他的(更好)的方式。
忘记了错误的来源了一下(我年年开发周期还在调试中),这将是很好的能够捕获这些错误并产生一个整洁的小堆栈跟踪可能停留在代码一直到部署和让用户时,事情会出错我们知道。 最后,我想换错误报告到的东西,可以通过网络报告。
如果反射在不同的线程发生的,包装是不会抓住它失败。
我找到了解决方法(使用申请:: 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 );
}
};