.net Try/Catch on Application.Run在调试器中工作,但不';运行实际应用程序时无法工作

.net Try/Catch on Application.Run在调试器中工作,但不';运行实际应用程序时无法工作,.net,vb.net,error-handling,.net,Vb.net,Error Handling,我用VB.NET做了一个项目。如果我的应用程序将产生一个不需要的错误,它将创建一个包含该错误的文本文件。在VisualStudio上运行它时,我能够做到这一点,但在运行单独的应用程序(在bin/Debug上找到的可执行文件)时,它不起作用 以下是我所做的: Sub Main(ByVal ParamArray args() As String) Try System.Windows.Forms.Application.Run(New Form1) Catch ex As Exception

我用VB.NET做了一个项目。如果我的应用程序将产生一个不需要的错误,它将创建一个包含该错误的文本文件。在VisualStudio上运行它时,我能够做到这一点,但在运行单独的应用程序(在bin/Debug上找到的可执行文件)时,它不起作用

以下是我所做的:

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
Sub Main(ByVal paramary args()作为字符串)
尝试
System.Windows.Forms.Application.Run(新表单1)
特例
WriteErrorLogs(ex)
结束尝试
端接头
子写入错误日志(Byval ex作为例外)
'创建一个文本文件,写入x.Message、x.Source、x.ToString
Dim dnow As String=Now.ToString
Dim文件名为String=“Error”&removeInvalidChars(dnow)
Dim saveto As String=New IO.FileInfo(“Errors/”&filename).FullName&“.txt”
标题为字符串=例如消息
Dim stacktrce As String=ex.StackTrace
如果不存在IO.Directory.Exists(新的IO.DirectoryInfo(“Errors”).FullName),则为IO.Directory.CreateDirectory(“Errors”)
将fw调为新IO.StreamWriter(保存到,False,System.Text.Encoding.UTF8)
fw.WriteLine(标题)
fw.WriteLine()
fw.WriteLine(stacktrce)
fw.Close()
端接头
私有函数removeInvalidChars(ByRef s作为字符串)
Dim invalidChars()为Char=“\/:*?”“|”。ToCharray
对于每个i作为无效字符中的字符
s=s。替换(i,“.”)
下一个
返回s
端函数
有更好的解决办法吗

  Try
      System.Windows.Forms.Application.Run(New Form1)
  Catch ex As Exception
      WriteErrorLogs(ex)
  End Try
是的,当您在没有附加调试程序的情况下运行此程序时,Catch子句永远不会捕获异常。在UI线程上引发的异常将被重新路由并触发Application.ThreadException事件。默认情况下,它会显示一个对话框,当您从bin\Debug目录运行它时,应该注意到

当您附加了调试器时,它的工作方式就不同了,当您需要调试未处理的异常时,该对话框确实会妨碍您。因此,故意禁用ThreadException事件,调试器会向您显示代码崩溃的位置。这不会发生在您编写的代码中,因为Catch子句确实捕获了异常

当您的程序由于工作线程上引发的未处理异常而崩溃时,Catch子句也将不起作用,它只能在UI线程上看到异常

您将需要一个更可靠的方法,您可以从AppDomain.UnhandledException事件中获得一个。对于任何未处理的异常都会引发该异常,而不管它是在哪个线程上引发的。将代码改为如下所示:

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

使用Debugger.IsAttached可确保您可以使用调试器诊断未处理的异常。使用Application.SetUnhandledExceptionMode可确保从不显示对话框并记录所有异常。

WriteErrorLogs方法中的代码在哪里?不清楚您在这里寻求的帮助是什么。你要写的文件在哪里?您不能写入文本文件的问题,或者更多的问题是关于错误处理最佳实践的查询吗?此外,有很多方法可以处理日志记录。在I detailed
log4net
中,您必须小心
WriteErrorLogs
中的代码不会引发错误。例如,如果它试图写入C:\驱动器的根目录,则可能会失败。(已完成代码)我的问题是,当不处于调试模式时,Try-Catch错误陷阱不起作用。假设Form1有一个调用错误的按钮。错误将被抛出到Sub Main上的Catch上。现在,我想知道是否有更好的解决方案,而不是使用Try-Catch-error-trap,因为它在已部署的应用程序上不起作用。这正是我想要的。谢谢@Hans+1虽然这个答案是在VB.Net中,但它对我很有帮助,因为它与我需要的C#实现几乎相同。