このコード スニペット ( 64 ビット バージョンの Windows で実行されるアプリケーションからスローされる Microsoft の例外は無視されます) を使用して、Windows が例外を無視しないようにすることができます。これをプロセス コードに挿入します。
// my SDK is v6.0A and the two APIs are not available in the .h files, so I need to get them at runtime
#define PROCESS_CALLBACK_FILTER_ENABLED 0x1
typedef BOOL (WINAPI *GETPROCESSUSERMODEEXCEPTIONPOLICY)(__out LPDWORD lpFlags);
typedef BOOL (WINAPI *SETPROCESSUSERMODEEXCEPTIONPOLICY)(__in DWORD dwFlags );
HINSTANCE h = ::LoadLibrary(L"kernel32.dll");
if ( h ) {
GETPROCESSUSERMODEEXCEPTIONPOLICY GetProcessUserModeExceptionPolicy = reinterpret_cast< GETPROCESSUSERMODEEXCEPTIONPOLICY >( ::GetProcAddress(h, "GetProcessUserModeExceptionPolicy") );
SETPROCESSUSERMODEEXCEPTIONPOLICY SetProcessUserModeExceptionPolicy = reinterpret_cast< SETPROCESSUSERMODEEXCEPTIONPOLICY >( ::GetProcAddress(h, "SetProcessUserModeExceptionPolicy") );
if ( GetProcessUserModeExceptionPolicy == 0 || SetProcessUserModeExceptionPolicy == 0 ) {
return;
}
DWORD dwFlags;
if (GetProcessUserModeExceptionPolicy(&dwFlags)) {
SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED);
}
}
未処理の例外フィルターも追加する必要がある場合があります。フィルターは、最上位catch
ブロックのような「トップレベルの例外ハンドラー」のように機能します。_EXCEPTION_POINTERS からプログラマー向けの文字列を抽出するには、EXCEPTION_POINTERS 構造体を文字列に変換する関数はありますか? を参照してください。
LONG WINAPI my_filter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
::OutputDebugStringA("an exception occured!");
return EXCEPTION_EXECUTE_HANDLER;
}
次のようにフィルターを追加します。
::SetUnhandledExceptionFilter(my_filter);
プロセスのすべてのスレッドでそれを行う必要があります。前のスニペットはプロセスごとですが、フィルターはスレッドごとです。