それを使用する代わりに、ここに記載されているように(and )<legacyCorruptedStateExceptionsPolicy>
を使用することをお勧めします。[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx
その後、Main
メソッドは次のようになります。
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main(string[] args)
{
try
{
...
}
catch (Exception ex)
{
// Log the CSE.
}
}
StackOverflowException
ただし、これはや などのより深刻な例外をキャッチしないことに注意してExecutionEngineException
ください。
finally
関連するブロックもtry
実行されません:
https://csharp.2000things.com/2013/08/30/920-a-finally-block-is-not-executed-when-a-corrupted-state-exception-occurs/
その他の未処理の appdomain 例外については、次を使用できます。
AppDomain.CurrentDomain.UnhandledException
Application.Current.DispatcherUnhandledException
TaskScheduler.UnobservedTaskException
(特定のハンドラーが状況に適している場合は、詳細を検索してください。TaskScheduler.UnobservedTaskException
たとえば、少しトリッキーです。)
メソッドにアクセスできない場合はMain
、AppDomain 例外ハンドラーをマークして CSE をキャッチすることもできます。
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
...
[HandleProcessCorruptedStateExceptions, SecurityCritical]
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// AccessViolationExceptions will get caught here but you cannot stop
// the termination of the process if e.IsTerminating is true.
}
防御の最後の行は、次のような管理されていない UnhandledExceptionFilter である可能性があります。
[DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
private static extern int SetUnhandledExceptionFilter(Callback cb);
// This has to be an own non generic delegate because generic delegates cannot be marshalled to unmanaged code.
private delegate uint Callback(IntPtr ptrToExceptionInfo);
そして、プロセスの最初のどこかで:
SetUnhandledExceptionFilter(ptrToExceptionInfo =>
{
var errorCode = "0x" + Marshal.GetExceptionCode().ToString("x2");
...
return 1;
});
考えられるリターン コードの詳細については、次を参照してください。
https://msdn.microsoft.com/en-us/library/ms680634(VS.85).aspx
の「特殊性」はUnhandledExceptionFilter
、デバッガーがアタッチされている場合は呼び出されないことです。(少なくとも、WPF アプリを使用している私の場合はそうではありません。)そのことに注意してください。
上記の適切な ExceptionHandlers をすべて設定すると、ログに記録できるすべての例外がログに記録されます。より深刻な例外 (StackOverflowException
や などExecutionEngineException
) については、発生後にプロセス全体が使用できなくなるため、別の方法を見つける必要があります。考えられる方法は、メイン プロセスを監視し、致命的なエラーをログに記録する別のプロセスである可能性があります。
追加のヒント:
- 心配することなく
AppDomain.CurrentDomain.UnhandledException
安全にキャストできます- 少なくとも 以外のオブジェクトをスローする IL コードがない場合:e.ExceptionObject
Exception
Exception
- Windows エラー報告ダイアログを抑制したい場合は、こちらをご覧ください:クラッシュ時にプログラムを終了する方法は? (永遠にスタックするのではなく、単体テストに失敗するはずです)
- 複数のディスパッチャーを持つ WPF アプリケーションがある場合は
Dispatcher.UnhandledException
、他のディスパッチャーに を使用することもできます。