2009-01-23 15 views
9

Ich arbeite an einem ziemlich großen Projekt, und es wird unwahrscheinlich alles fangen. Ich habe das Ereignis gefunden, das mich über nicht behandelte Ausnahmen benachrichtigt, jedoch habe ich keinen Weg gefunden, den Windows-Fehlerdialog programmatisch zu beenden. Im Idealfall möchte ich, wenn eine nicht behandelte Ausnahme vorliegt, dieses Ereignis ausgelöst haben, ein Dialogfeld bereitstellen, das dem Benutzer mitteilt, dass ein Problem vorliegt, und dann ordnungsgemäß schließen. Gibt es eine Möglichkeit, dies zu tun? Ich weiß, dass ich die höchste Schicht in einen Versuch fangen konnte, aber ich hoffte etwas eleganteres.Verhindern "Fehlerbericht an Microsoft senden"

Antwort

5

Das haben wir gemacht.

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

Warum wurde ich abgelehnt? –

+0

Warum implementieren Sie AppDomain.UnhandledException * und * das gesamte Ding in einen Try/Catch-Block? Das ist dumme Gans. –

3

Sie haben irgendwie Ihre eigene Frage beantwortet. Der beste Weg, um den Fehlerdialog zu verhindern, besteht darin, Code zu schreiben, der Ihre Ausnahmen behandelt, so dass der Dialog niemals erscheint. Ich wette, das ist, was Raymond Chen vorschlagen würde (wenn ich so mutig sein könnte).

+0

Ein globaler Versuch/Fang (wie die erste Antwort) ist, was ich in Betracht gezogen habe. Ich war mir nur nicht sicher, ob das eine Best Practice war oder nicht. Ich war mir auch nicht sicher, ob es einen saubereren Weg dafür gab. – Steve

-2

Sie können versuchen, mit HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ Currentversion \ AeDebug

Das Spitze Form DrWatson Tage spielen .. kann oder auch nicht.

+1

Meckern Sie nicht mit systemweiten Einstellungen, wenn Sie versuchen, ein app-spezifisches Problem zu lösen –

+0

- Benutzern mag die Tatsache nicht gefallen, dass Sie ihre Einstellungen ändern ... - Ihre Anwendung hat möglicherweise keinen Schreibzugriff auf diese Registrierung Schlüssel. –

0

Wenn Ihre Frage in Bezug auf eine WinForms-Anwendung war, dann wird die ausgewählte Antwort für Sie funktionieren, aber es ist nicht gerade elegant.

.NET bietet einen Assistenten für genau dieses Szenario:

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

And here's the MSDN Documentation on the method

1

Wenn Sie .NET Framework 2.0 oder höher verwenden und es gibt eine nicht behandelte Ausnahme von einem Worker-Thread, ich glaub du bin kein Glück. In .NET 1.0 und 1.1 verschluckte CLR einfach die Ausnahme von einem anderen Thread als dem Hauptthread. Dies wurde jedoch in .NET 2.0 geändert, wo eine nicht behandelte Ausnahme in einem Thread zum Herunterfahren der Anwendung führt.

Sie können AppDomain.CurrentDomain.UnhandledException abonnieren, um benachrichtigt zu werden, wenn diese Art von nicht behandelten Ausnahmen auftreten, aber die Anwendung wird wahrscheinlich zu diesem Zeitpunkt heruntergefahren und Sie haben nur eine Chance, Dinge vor dem unvermeidlichen wie Protokollierung zu tun die Ausnahme irgendwo und Anzeige benutzerfreundliche Nachricht. UnhandledExceptionEventArgs verfügt über eine schreibgeschützte Eigenschaft mit dem Namen IsTerminating, mit der überprüft werden kann, ob die Anwendung beendet wird oder nicht. Nachdem die Anwendung beendet wird, erscheint normalerweise das Microsoft-Fehlermeldungsdialogfeld.

Während ich dies nicht empfehlen würde, gibt es eine Möglichkeit, zurück zum Verhalten von CLR 1.0 und 1.1 zu wechseln, indem Sie das Flag für die Anwendungskompatibilität in der App-Konfigurationsdatei festlegen.

Dies sollte die Anwendung nicht dazu führen, in Fällen von nicht behandelten Ausnahmen zu beenden und die Wahrscheinlichkeit des Erhaltens, dass die Fehlermeldung Dialog zu reduzieren.

Meine Empfehlung wäre, nur die Ausnahmen abzufangen, die Sie erwarten und in Ihrem Code verarbeiten können und die anderen aufblühen lassen.

+0

Es hängt davon ab, wie Sie Ihre Worker-Threads verwalten. Meine bevorzugte Vorgehensweise für alle Jobs mit nicht langer Laufzeit ist die Verwendung von Delegate.BeginInvoke(), um einen ThreadPool-Thread zum Ausführen der asynchronen Aktion zu verwenden. Wenn Sie dies tun, gibt der Thread eine Ausnahme beim Aufruf von EndInvoke() zurück - Sie müssen nur dafür sorgen, dass EndInvoke für jedes BeginInvoke aufgerufen wird (dies kann jedoch nicht zu Ressourcenlecks führen). – STW

Verwandte Themen