3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(C#)ハンドルされない例外を捕まえる方法

以前に(VB.Net)ハンドルされない例外を捕まえる方法という記事を書きましたが、この内容のC#版のコードをメモ代わりに載せておきます。

まず、メインフォームのコンストラクタに以下のイベントハンドラを登録します。

//キャッチされない例外をとらえるイベント

Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

System.Threading.Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException);

イベントハンドラは以下のようになります。

/// 

/// 未処理例外をキャッチするイベントハンドラ。メインスレッド用。(WindowsForm専用)

///

///

///

public static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e){

string sourceName = Properties.Settings.Default.AppName; //ソフト名が入っていることとする

//イベントログ出力

OutPutLogErr(e.Exception);

//メッセージボックス表示

MessageBox.Show("エラーが発生しました。処理を中断します。\nエラー情報:" + e.Exception.Message, sourceName, MessageBoxButtons.OK, MessageBoxIcon.Error);

//予期せぬ例外時は強制終了

Environment.Exit(-1);

}

 

///

/// 未処理例外をキャッチするイベントハンドラ。別スレッドorコンソールアプリ用

///

///

///

public static void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e){

string sourceName = Properties.Settings.Default.AppName;

Exception ex = (Exception)e.ExceptionObject;

if (ex != null) {

//イベントログ出力

OutPutLogErr(ex);

//メッセージボックス表示

MessageBox.Show("エラーが発生しました。処理を中断します。\nエラー情報:" + ex.Message, sourceName, MessageBoxButtons.OK, MessageBoxIcon.Error);

//予期せぬ例外時は強制終了

Environment.Exit(-1);

}

}

 

 

///

/// エラーをイベントログに出力。

///

///

public static void OutPutLogErr(Exception e){

try{

string sourceName = Properties.Settings.Default.AppName;

if (!System.Diagnostics.EventLog.SourceExists(sourceName))

{

//ログ名を空白にすると、"Application"となる

System.Diagnostics.EventLog.CreateEventSource(sourceName, "");

}

byte[] myData = { };

string msg = "例外\n:" + e.Message + "\n例外スタックトレース:\n" + e.StackTrace + "\n";

if (e.InnerException != null)

{

msg = msg + "InnerException:\n" + e.InnerException.Message + "\nInnerExceptionスタックトレース:\n" + e.InnerException.StackTrace;

}

//イベントログにエントリを書き込む

//ここではエントリの種類をエラー、イベントIDを1、分類を1000とする

System.Diagnostics.EventLog.WriteEntry(sourceName, msg, System.Diagnostics.EventLogEntryType.Error, 1, 1000, myData);

} catch (Exception){

return;

}

}