51

製品のエラー処理の一部として、スタック トレース情報をダンプしたいと考えています。ただし、多くのユーザーは、プログラムから入手できる完全なレポートのコピーを送信する代わりに、エラー メッセージ ダイアログのスクリーンショットを撮るだけで済みます。そのため、このダイアログで最小限のスタック トレース情報を入手できるようにしたいと考えています。

私のマシンの .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キーワードとinキーワードは、たとえば、インストールした英語の .NET ランタイムではなく、ノルウェー語の .NET ランタイムを実行する場合、ローカライズされると思います。

このスタック トレースを言語に依存しない方法で分離して、これを含むエントリのファイルと行番号のみを表示できるようにする方法はありますか?

つまり、上記のテキストから次の情報を取得したいと思います。

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

あなたが与えることができるアドバイスは役に立ちます。

4

5 に答える 5

71

と言って、文字列の代わりに StackTrace オブジェクトを取得できるはずです。

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

その後、フレームワークのフォーマットに依存することなく、フレームを自分で見ることができます。

参照: StackTrace リファレンス

于 2008-09-09T13:01:01.107 に答える
28

例外なくこれを行うために使用するコードは次のとおりです

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));
  }
}
于 2009-08-06T14:08:48.937 に答える
19

これを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();
}

(リンドホルムの回答に基づく)

于 2011-05-22T13:26:59.303 に答える
9

またはさらに短いバージョンがあります..

Console.Write(exception.StackTrace);
于 2012-01-08T17:34:01.423 に答える
1

別の方法として、log4net は潜在的に危険ではありますが、System.Diagnostics よりも良い結果をもたらしました。基本的に、log4net には、さまざまなログ レベルのメソッドがあり、それぞれに Exception パラメータがあります。したがって、2 番目の例外を渡すと、構成したアペンダーにスタック トレースが出力されます。

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

構成に応じて、出力は次のようになります。

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
   ...
于 2008-09-09T13:06:03.683 に答える