Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
305 views
in Technique[技术] by (71.8m points)

.net - Try/Catch on Application.Run works in debugger, but doesn't work when running the actual application

I made a project in VB.NET. If the application I made will produce an unwanted error, it will create a text file containing the error. I was able to do this when running it on Visual Studio but it does not work when running the separate application, the executable file found on bin/Debug.

Here's what I've done:

Sub Main(ByVal ParamArray args() As String)
  Try
System.Windows.Forms.Application.Run(New Form1)
  Catch ex As Exception
WriteErrorLogs(ex)
  End Try
End Sub

Sub WriteErrorLogs(Byval ex As Exception)
' create a textfile the write x.Message, x.Source, x.ToString
  Dim dnow As String = Now.ToString
  Dim filename As String = "Error " & removeInvalidChars(dnow)
  Dim saveto As String = New IO.FileInfo("Errors/" & filename).FullName & ".txt"
  Dim title As String = ex.Message
  Dim stacktrce As String = ex.StackTrace

  If Not IO.Directory.Exists(New IO.DirectoryInfo("Errors").FullName) Then IO.Directory.CreateDirectory("Errors")
  Dim fw As New IO.StreamWriter(saveto, False, System.Text.Encoding.UTF8)
  fw.WriteLine(title)
  fw.WriteLine()
  fw.WriteLine(stacktrce)
  fw.Close()
End Sub

Private Function removeInvalidChars(ByRef s As String)
  Dim invalidChars() As Char = "/:*?""<>|".ToCharArray
  For Each i As Char In invalidChars
    s = s.Replace(i, ".")
  Next
  Return s
End Function

Is there a better solution for this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
  Try
      System.Windows.Forms.Application.Run(New Form1)
  Catch ex As Exception
      WriteErrorLogs(ex)
  End Try

Yes, that Catch clause is never going to catch an exception when you run this without a debugger attached. Exceptions that are raised on the UI thread are rerouted and trigger the Application.ThreadException event instead. Which by default displays a dialog, you should have noticed that when you ran it from the binDebug directory.

It works differently when you have a debugger attached, that dialog really gets in the way when you need to debug unhandled exceptions. So the ThreadException event is intentionally disabled and the debugger shows you where your code has crashed. Which will not happen with the code you wrote, now that Catch clause does catch the exception.

The Catch clause also will not work when your program crashed due to an unhandled exception that was raised on a worker thread, it can only see exceptions on the UI thread.

You will need a more solid approach, you can get one from the AppDomain.UnhandledException event. Which is raised for any unhandled exception, regardless of what thread it was raised on. Make your code look like this instead:

Module Module1
    Public Sub Main(ByVal args() As String)
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        If Not System.Diagnostics.Debugger.IsAttached Then
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)
            AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf LogUnhandledExceptions
        End If
        Application.Run(New Form1())
    End Sub

    Private Sub LogUnhandledExceptions(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
        Dim ex = DirectCast(e.ExceptionObject, Exception)
        '' Log or display ex.ToString()
        ''...
        Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex))
    End Sub
End Module

Using Debugger.IsAttached ensures that you can diagnose unhandled exceptions with the debugger. Using Application.SetUnhandledExceptionMode ensures that the dialog is never displayed and all exceptions are logged.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...