This one has me stumped. I'd swear this behaved differently prior to .NET 1.1 service pack 1 (and/or XP SP2), but I can't prove it. As reported by a CodeProject reader, you'll get the standard .NET crash dialog in a console app, even if you've registered an unhandled exception handler for your AppDomain. What gives? Why doesn't AppDomain.CurrentDomain.UnhandledException capture exceptions on the main thread of a .NET console application?
But don't take my word for it-- try it yourself. Use this sample (source code zip file) from John Robbins, co-founder of Wintellect. Or, paste the code from this MSDN article into a new console app and run it:
Sub Main() Dim cd As AppDomain = AppDomain.CurrentDomain AddHandler cd.UnhandledException, AddressOf MyHandler Try Throw New Exception("1") Catch e As Exception Console.WriteLine("Catch clause caught : " + e.Message) End Try Throw New Exception("2") ' Expected output: ' Catch clause caught : 1 ' MyHandler caught : 2 End Sub Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs) Dim e As Exception = DirectCast(args.ExceptionObject, Exception) Console.WriteLine("MyHandler caught : " + e.Message) End Sub
At first I was concerned that installing VS.NET had somehow forced me into some kind of bizarre first-chance exception mode exclusive to console applications, but not so. The compiled .exe behaves in the same way on every machine I tried it on: I get the standard .NET crash dialog, then after I dismiss that, I get the unhandled exception handler I wanted in the first place. That's.. not exactly the order I had in mind.
There's a way to disable the .NET JIT debugging dialog, as described by Scott Hanselman. But that's an extreme "solution": it disables the crash dialog for all .NET apps. It's also treating the symptoms rather than the disease: why can't we catch unhandled exceptions in console apps any more? I'd swear this worked the last time I looked at it. And the MSDN sample code certainly implies that it's possible-- but good luck getting that sample to print the expected output.
So what am I missing here?