从C#打印堆栈跟踪信息

作为我们产品中某些error handling的一部分,我们想转储一些堆栈跟踪信息。 然而,我们体验到,许多用户只是截取错误消息对话框的屏幕截图,而不是向我们发送程序中提供的完整报告的副本,因此我想在此对话框中提供一些最小的堆栈跟踪信息。

我的机器上的.NET堆栈跟踪如下所示:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize) at System.IO.StreamReader..ctor(String path) at LVKWinFormsSandbox.MainForm.button1_Click(Object sender, EventArgs e) in C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

我有这个问题:

格式看起来是这样的:

 at <class/method> [in file:line ##] 

然而, 关键字at和关键字,我假设这些将被本地化,如果他们运行,而不是我已经安装的英文版,而不是一个挪威的.NET运行时。

有没有办法让我以一种与语言无关的方式挑选这个堆栈跟踪,以便我只能显示那些有这个条目的文件和行号?

换句话说,我想从上面的文字中获得这些信息:

 C:\Dev\VS.NET\Gatsoft\LVKWinFormsSandbox\MainForm.cs:line 36 

任何build议,您可以给予帮助。

你应该可以得到一个StackTrace对象而不是string

 var trace = new System.Diagnostics.StackTrace(exception); 

然后,您可以自己查看框架而不依赖框架的格式。

另请参见: StackTrace参考

这里是我用来做这个没有例外的代码

 public static void LogStack() { var trace = new System.Diagnostics.StackTrace(); foreach (var frame in trace.GetFrames()) { var method = frame.GetMethod(); if (method.Name.Equals("LogStack")) continue; Log.Debug(string.Format("{0}::{1}", method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, method.Name)); } } 

只是为了让这15秒的复制粘贴答案:

 static public string StackTraceToString() { StringBuilder sb = new StringBuilder(256); var frames = new System.Diagnostics.StackTrace().GetFrames(); for (int i = 1; i < frames.Length; i++) /* Ignore current StackTraceToString method...*/ { var currFrame = frames[i]; var method = currFrame.GetMethod(); sb.AppendLine(string.Format("{0}:{1}", method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, method.Name)); } return sb.ToString(); } 

(根据Lindholm的答案)

或者甚至有更短的版本..

 Console.Write(exception.StackTrace); 

另外,log4net虽然有潜在的危险,但却给了我比System.Diagnostics更好的结果。 基本上在log4net中,你有一个不同的日志级别的方法,每个级别都有一个Exception参数。 所以,当你传递第二个exception时,它会将堆栈跟踪打印到你已经configuration的appender。

例如: Logger.Error("Danger!!!", myException );

输出,取决于configuration,看起来像

 System.ApplicationException: Something went wrong. at Adapter.WriteToFile(OleDbCommand cmd) in C:\Adapter.vb:line 35 at Adapter.GetDistributionDocument(Int32 id) in C:\Adapter.vb:line 181 ...