2009-01-23 21 views
9

Estoy trabajando en un proyecto bastante grande, y es poco probable que atrape todo. He encontrado el evento que me notifica las excepciones no controladas, sin embargo, no he encontrado la forma de cerrar programáticamente el cuadro de diálogo de error de Windows. Idealmente, si hay una excepción no controlada, me gustaría que se desencadene ese evento, proporcionar un cuadro de diálogo que indique al usuario que hay un problema y luego cerrar con gracia. ¿Hay alguna manera de hacer esto? Me di cuenta de que podía envolver la capa más alta en una captura de prueba, pero esperaba algo un poco más elegante.Prevenir "Enviar informe de errores a Microsoft"

Respuesta

5

Esto es lo que hicimos.

static void Main() { 
    try 
    { 
     SubMain(); 
    } 
    catch (Exception e) 
    { 
     HandleUnhandledException(e); 
    } 
} 

private static void SubMain() 
{ 
    // Setup unhandled exception handlers 
    AppDomain.CurrentDomain.UnhandledException += // CLR 
     new UnhandledExceptionEventHandler(OnUnhandledException); 
    Application.ThreadException += // Windows Forms 
     new System.Threading.ThreadExceptionEventHandler(
      OnGuiUnhandledException); 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new frmMain()); 
} 

// CLR unhandled exception 
private static void OnUnhandledException(Object sender, 
    UnhandledExceptionEventArgs e) 
{ 
    HandleUnhandledException(e.ExceptionObject); 
} 

// Windows Forms unhandled exception 
private static void OnGuiUnhandledException(Object sender, 
    System.Threading.ThreadExceptionEventArgs e) 
{ 
    HandleUnhandledException(e.Exception); 
} 
+1

¿Por qué me dieron downvoted? –

+0

¿Por qué implementa AppDomain.UnhandledException * y * envuelve todo en un bloque Try/Catch? Eso es tonto. –

3

Has respondido a tu pregunta. La mejor forma de evitar el diálogo de error es escribir código que maneje sus excepciones para que el cuadro de diálogo nunca aparezca. Apostaría a que esto es lo que Raymond Chen sugeriría (si puedo ser tan audaz).

+0

Un try/catch global (como la primera respuesta) es lo que estaba considerando. Simplemente no estaba seguro de si eso era una buena práctica o no. Tampoco estaba seguro de si había una forma más limpia de hacerlo. – Steve

-2

Puede intentar jugando con HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ AeDebug

que la punta es de forma Drwatson días .. Puede o no puede trabajar.

+1

No ensucie con la configuración de todo el sistema si está tratando de resolver un problema específico de la aplicación –

+0

- Puede que a los usuarios no les guste el hecho de que cambie su configuración ... - Su aplicación puede no tener acceso de escritura a este registro llave. –

0

Si su pregunta fue con respecto a una aplicación de WinForms, entonces la respuesta seleccionada funcionará para usted, sin embargo, no es exactamente elegante.

.NET proporciona un asistente para este escenario exacto:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) 
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException 

And here's the MSDN Documentation on the method

1

Si está utilizando .NET Framework 2.0 o posterior y no hay una excepción no controlada desde un subproceso de trabajo, lo que belive Está fuera de suerte. En .NET 1.0 y 1.1, CLR simplemente se tragó la excepción de un hilo que no sea el hilo principal. Sin embargo, esto se modificó en .NET 2.0, donde una excepción no controlada en un hilo provoca el cierre de la aplicación.

Puede suscribirse a AppDomain.CurrentDomain.UnhandledException para recibir notificaciones cuando ocurran este tipo de excepciones no controladas, pero la aplicación probablemente se cierre en este punto y se le dé la oportunidad de hacer cosas antes del inevitable registro como la excepción en algún lugar y muestra un mensaje fácil de usar. UnhandledExceptionEventArgs tiene una propiedad de solo lectura llamada IsTerminating que puede inspeccionar para ver si la aplicación está terminando o no. Una vez que la aplicación finaliza, generalmente aparece el cuadro de diálogo de informe de error de Microsoft.

Si bien no lo recomendaría, hay una forma de volver al comportamiento de CLR 1.0 y 1.1 estableciendo el indicador de compatibilidad de aplicaciones en el archivo de configuración de la aplicación.

Esto no debería causar la aplicación para terminar en los casos de excepciones no controladas y reducir la probabilidad de conseguir que el diálogo de informe de errores.

Mi recomendación sería atrapar solo las excepciones que anticipa y puede manejar en su código y dejar que las otras aparezcan.

+0

Depende de cómo administre sus hilos de trabajo. Mi enfoque preferido para todos los trabajos que no son de larga duración es usar Delegate.BeginInvoke() para usar un hilo de ThreadPool para realizar la acción asincrónica. Si haces esto, el hilo devolverá cualquier excepción cuando invoques a EndInvoke(); solo tienes que asegurarte de que se invoque EndInvoke para cada BeginInvoke (no hacerlo puede dar lugar a fugas de recursos). – STW

Cuestiones relacionadas