A summary from the answers by jdehaan and Eric Brown, as well as this question (see also this question):
N.B. These solutions may affect other error reporting as well, e.g. failure to load a DLL or open a file.
Option 1: Disable globally
Works globally on the entire user account or machine, which can be both a benefit and a drawback.
Set [HKLM|HKCU]SoftwareMicrosoftWindowsWindows Error ReportingDontShowUI
to 1.
More info: WER settings.
Option 2: Disable for the application
Requires modification to the crashing program, described in documentation as best practice, unsuitable for a library function.
Call SetErrorMode: SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
(or with SEM_FAILCRITICALERRORS
). More info: Disabling the program crash dialog (explains the odd arrangement of calls).
Option 2a: Disable for a function:
Requires modification to the crashing program, requires Windows 7/2008 R2 (desktop apps only) or higher, described in documenation as preferred to SetErrorMode
, suitable for a thread-safe library function.
Call and reset SetThreadErrorMode:
DWORD OldThreadErrorMode = 0;
SetThreadErrorMode(SEM_FAILCRITICALERRORS,& OldThreadErrorMode);
…
SetThreadErrorMode (z_OldThreadErrorMode, NULL);
More info: not much available?
Option 3: Specify a handler
Requires modification to the crashing program.
Use SetUnhandledExceptionFilter
to set your own structured exception handler that simply exits, probably with reporting and possibly an attempt at clean-up.
Option 4: Catch as an exception
Requires modification to the crashing program. For .NET applications only.
Wrap all code into a global try/catch block. Specify the HandleProcessCorruptedStateExceptionsAttribute
and possibly also the SecurityCriticalAttribute
on the method catching the exceptions. More info: Handling corrupted state exceptions
Note: this might not catch crashes caused by the Managed Debugging Assistants; if so, these also need to be disabled in the application.
Option 5: Stop the reporting process
Works globally on the entire user account, but only for a controlled duration.
Kill the Windows Error Reporting process whenever it shows up:
var werKiller = new Thread(() =>
{
while (true)
{
foreach (var proc in Process.GetProcessesByName("WerFault"))
proc.Kill();
Thread.Sleep(3000);
}
});
werKiller.IsBackground = true;
werKiller.Start();
This is still not completely bullet-proof though, because a console application may crash via a different error message, apparently displayed by an internal function called NtRaiseHardError
: