集約例外ハンドラを使ってみた - VB.NET
アプリケーションフレームワークを無効にしてしまうと、My.Application.ApplicationContextが使えなくなるため、ApplicationEventsを使う方法がいいかも。My.Application.ApplicationContext
はMainFormを入れ替えるときに使うから無効にしたくないときとか。
ApplicationEventsにUnhandledExceptionを追加し、集約例外ハンドラを実装
プロジェクトのプロパティ > アプリケーション > アプリケーションイベントの表示 をクリックするとApplicationEvents.vb
が表示される。Application.vb
を以下のように編集する
Imports Microsoft.VisualBasic.ApplicationServices Namespace My ' 次のイベントは MyApplication に対して利用できます: ' Startup:アプリケーションが開始されたとき、スタートアップ フォームが作成される前に発生します。 ' Shutdown:アプリケーション フォームがすべて閉じられた後に発生します。このイベントは、アプリケーションが異常終了したときには発生しません。 ' UnhandledException:ハンドルされない例外がアプリケーションで発生したときに発生します。 ' StartupNextInstance:単一インスタンス アプリケーションが起動され、それが既にアクティブであるときに発生します。 ' NetworkAvailabilityChanged:ネットワーク接続が接続されたとき、または切断されたときに発生します。 Partial Friend Class MyApplication Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException MessageBox.Show("致命的なエラーが発生しました。" & vbLf & "システム担当者にご連絡ください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) ' ここはLog4netとか使うのかな Debug.Print(e.Exception.Message) Debug.Print(e.Exception.StackTrace) End Sub End Class End Namespace
UngandledExceptionが発生したら、アプリケーションは終了してしまうが、それはしょうがない...
エントリポイントを作成し、Application.ThreadExceptionを追加し、集約例外ハンドラを実装
補足されていない例外をキャッチするにはApplication.ThreadException
イベントでキャッチできる。
エントリポイント(Main())を記述したモジュールをスタートアップオブジェクトに設定することで集約例外ハンドラを使える。
Module EntryPoint <STAThread()> Sub Main() ' UIスレッドの集約例外ハンドラ AddHandler Application.ThreadException, AddressOf Application_ThreadException ' UIスレッド以外の集約例外ハンドラ AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) Application.Run(New Form1()) End Sub ''' <summary> ''' UIスレッドの集約例外ハンドラ。 ''' </summary> Sub Application_ThreadException(sender As Object, e As System.Threading.ThreadExceptionEventArgs) MessageBox.Show("致命的なエラーが発生しました。" & vbLf & "システム担当者にご連絡ください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Debug.Print(e.Exception.Message) Debug.Print(e.Exception.StackTrace) End Sub ''' <summary> ''' UIスレッド以外の集約例外ハンドラ。 ''' UnhandledException はアプリケーションが終了することを防止できない。 ''' </summary> Sub CurrentDomain_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) MessageBox.Show("致命的なエラーが発生しました。" & vbLf & "システム担当者にご連絡ください。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Debug.Print(CType(e.ExceptionObject, Exception).Message) Debug.Print(CType(e.ExceptionObject, Exception).StackTrace) Environment.Exit(-1) End Sub End Module