VBで「アプリケーションフレームワークを有効にする」をチェックONにしたときに、例外を一括処理する方法です。
C#ではアプリケーションのエントリーポインはMainメソッドになります。
補足されなかった例外を一括で処理する場合、このMainメソッド内で
System.Windows.Forms.Application.ThreadExceptionイベントと
System.AppDomain.CurrentDomain.UnhandledExceptionイベントをハンドルして処理すると思います。
VBでもエントリーポイントをMainメソッドにした場合、C#と同じ方法で補足されなかった例外を一括処理できます。
しかし、VBではデフォルトで「アプリケーションフレームワークを有効にする」チェックONなので
スタートアップフォームを指定してアプリケーションを起動することが多いように思います。
私に権限があれば自作のMainメソッドをエントリーポイントにしてアプリを起動するようにするのですが
(そのほうが細かいこともまで融通が利くので)
政治的な理由で「アプリケーションフレームワークを有効にする」チェックOFFにできない場合
アプリケーションイベントを使用して、補足されなかった例外を一括処理できます。
まずアプリケーションイベントとはVBにのみ用意されている、アプリケーションに関するイベントを記述することができるクラスです。
このクラスファイルはデフォルトでは非表示です。
まずはこのファイルを表示させます。
プロジェクトのプロパティ画面を開き「アプリケーション」タブにある「アプリケーションイベントの表示」をクリックします。

するとプロジェクト内に「ApplicationEvent.vb」ファイルが表示されます。

このファイルの中を見ると
名前空間は「My」クラス名は「MyApplication」になっています。
「Partial」キーワードが付いているので、どこかに分離されたコードがあります。

「My Project」の「Application.myapp」の「Application.Designer.vb」が分離されたコードになります。

MyApplicationクラスのコードのコメントに
「UnhandledException: ハンドルされていない例外がアプリケーションで発生したときに発生するイベントです。」とあるので
一見、これを使えばよさそうな気がします。
結論からいいますと、ダメでした。
例外の補足には
メインフォームが実行されているスレッド(UIスレッド)で発生する例外と
メインフォームが実行されているスレッド以外(UIスレッド以外)で発生する例外を補足する必要があります。
UIスレッドで発生する例外を補足するには
System.Windows.Forms.Application.ThreadExceptionイベントを使用します。
UIスレッド以外で発生する例外を補足するには
System.AppDomain.CurrentDomain.UnhandledExceptionイベントを使用します。
MyApplicationクラスのUnhandledExceptionイベントは、UIスレッドで発生する例外を補足できるようです。
UIスレッド以外で発生する例外を補足するために、StartUpイベントを使用して
System.AppDomain.CurrentDomain.UnhandledExceptionイベントをハンドルしてみました。
以下がダメな場合のコードです。
実行するとUIスレッドで発生した例外もすべて、CurrentDomain_UnhandledExceptionメソッドで処理されてしまいます。
ダメなコードです!!
Namespace My ' 次のイベントは MyApplication に対して利用できます: ' ' Startup: アプリケーションが開始されたとき、スタートアップ フォームが作成される前に発生します。 ' Shutdown: アプリケーション フォームがすべて閉じられた後に発生します。このイベントは、通常の終了以外の方法でアプリケーションが終了されたときには発生しません。 ' UnhandledException: ハンドルされていない例外がアプリケーションで発生したときに発生するイベントです。 ' StartupNextInstance: 単一インスタンス アプリケーションが起動され、それが既にアクティブであるときに発生します。 ' NetworkAvailabilityChanged: ネットワーク接続が接続されたとき、または切断されたときに発生します。 Partial Friend Class MyApplication Private Sub MyApplication_Startup(sender As Object, e As ApplicationServices.StartupEventArgs) Handles Me.Startup AddHandler System.AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException End Sub Private Sub MyApplication_UnhandledException(sender As Object, e As ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException 'アプリケーションを終了しない e.ExitApplication = False '例外メッセージを表示 MessageBox.Show(e.Exception.Message,"MyApplication_UnhandledException") End Sub Private Sub CurrentDomain_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) '例外メッセージを表示 MessageBox.Show(DirectCast(e.ExceptionObject, Exception).Message,"CurrentDomain_UnhandledException") End Sub End Class End NamespaceUIスレッド以外のスレッドは使用しないから、UnhandledExceptionイベントだけハンドルすればいいかと思ってたのですが
メインスレッドのコンストラクタ内で例外が発生すると、補足できません。
※コンストラクタで例外が発生するのがどうかと思うのですが、ごくたまにサードパーティ製のコントロールが例外をスローして
例外が補足できずに標準の例外が出てしまうことがありました。
OnInitializeメソッドをオーバーライドして
System.Windows.Forms.Application.ThreadExceptionイベントと
System.AppDomain.CurrentDomain.UnhandledExceptionイベントをハンドルすると、希望通りの動作になりました。
Namespace My ' 次のイベントは MyApplication に対して利用できます: ' ' Startup: アプリケーションが開始されたとき、スタートアップ フォームが作成される前に発生します。 ' Shutdown: アプリケーション フォームがすべて閉じられた後に発生します。このイベントは、通常の終了以外の方法でアプリケーションが終了されたときには発生しません。 ' UnhandledException: ハンドルされていない例外がアプリケーションで発生したときに発生するイベントです。 ' StartupNextInstance: 単一インスタンス アプリケーションが起動され、それが既にアクティブであるときに発生します。 ' NetworkAvailabilityChanged: ネットワーク接続が接続されたとき、または切断されたときに発生します。 Partial Friend Class MyApplication '''''' OnInitializeメソッドをオーバーライド ''' ''' '''''' Protected Overrides Function OnInitialize(commandLineArgs As ObjectModel.ReadOnlyCollection(Of String)) As Boolean 'ハンドルされていない例外を補足する '--UIスレッドでの例外を補足 AddHandler System.Windows.Forms.Application.ThreadException, AddressOf Application_ThreadException '--UIスレッド以外での例外を補足 AddHandler System.AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException Return MyBase.OnInitialize(commandLineArgs) End Function ''' ''' UIスレッドでの例外を補足するイベント ''' ''' ''' '''Private Sub Application_ThreadException(sender As Object, e As System.Threading.ThreadExceptionEventArgs) 'スプラッシュ画面を閉じる CloseSplashScreen() '例外処理を行う ShowError(e.Exception) End Sub ''' ''' UIスレッド以外での例外を補足するイベント ''' ''' ''' '''Private Sub CurrentDomain_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) '※UIスレッド以外のスレッドなので、UIスレッドの画面操作はできない '----- ''スプラッシュ画面を閉じる 'CloseSplashScreen() '----- '例外処理を行う ShowError(DirectCast(e.ExceptionObject, Exception)) End Sub ''' ''' スプラッシュ画面を閉じる ''' '''Private Sub CloseSplashScreen() If (My.Application.SplashScreen IsNot Nothing AndAlso My.Application.SplashScreen.IsDisposed <> True) Then My.Application.SplashScreen.Close() End If End Sub ''' ''' 例外処理を行う ''' ''' '''Private Sub ShowError(ex As Exception) Dim info As New System.Text.StringBuilder info.AppendLine(ex.Message) info.AppendLine(ex.StackTrace) info.AppendLine("------メソッド呼出履歴------") For Each frm As StackFrame In New StackTrace(ex, True).GetFrames Dim mb As System.Reflection.MethodBase = frm.GetMethod info.AppendLine(mb.ReflectedType.FullName & " : " & mb.Name) Next MessageBox.Show(info.ToString) End Sub End Class End Namespace