質問

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

私のマシン上の .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 ##]

しかし そして キーワードについては、インストールした英語の .NET ランタイムではなく、ノルウェー語の .NET ランタイムを実行するとローカライズされると思います。

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

言い換えれば、上記のテキストから次の情報が欲しいのです。

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

アドバイスをいただければ助かります。

役に立ちましたか?

解決

次のようにすることで、文字列の代わりに StackTrace オブジェクトを取得できるはずです。

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

これにより、フレームワークの書式設定に依存せずに自分でフレームを確認できるようになります。

以下も参照してください。 スタックトレースリファレンス

他のヒント

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

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

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

あるいは、さらに短いバージョンもあります。

Console.Write(exception.StackTrace);

代わりに、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
   ...
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top