We have an unmanaged C++ application that utilizes 3rd party APIs to read CAD files. On certain corrupted CAD files, the 3rd party library crashes and brings our EXE down with it. Because of this our main application is a separate EXE and in this way it does not get affected by the crash. Howevever, we end up with annoying Microsoft Error Reporting dialogs.
I do not want to disable Microsoft Error Reporting system wide. Is there a way to turn off error reporting for a single application, so that if it crashes, it crashes silently without error popup dialogs?
Step 1: Go to your system's settings. Open Storage and launch Free Up Space Now. Step 2: Select “System created Windows Error Reporting files” and check its box while leaving the other unchecked. Step 3: Click on the “Remove Files” button to successfully delete all the Windows Error Reporting files from your system.
To do this go to search and type services. msc and open it. Go to Windows Error Reporting Service. Open it and set it to disable and stop the service.
On Vista and above, the WerAddExcludedApplication API function can be used to exclude a specified application executable from error reporting. As far as I'm aware, there's no similar option on XP and other legacy OS versions.
However, since WER will only kick in on unhandled application exceptions, you should be able to suppress it by adding a "catch-all" exception handler to your EXE. See vectored exception handling for some ideas on how to achieve that.
Note that suppressing all unhandled exceptions is generally a bad idea (and will, for example, cause your app to fail Windows Logo certification), so you should not use this technique indiscriminately...
Yeah, there's something you can do. Call SetUnhandledExceptionFilter() in your main() method to register a callback. It will be called when nobody volunteers to handle the exception, just before the Microsoft WER dialog shows up.
Actually doing something in that callback is fraught with trouble. The program has died with, invariably, something nasty like an AccessViolation exception. Which often is tripped by heap corruption. Trying to do something like displaying a message box to let the user know is troublesome when the heap is toast. Deadlock is always lurking around the corner too, ready to just lock up the program without any diagnostic at all.
The only safe thing to do is to have a helper process that guards your main process. Wake it up by signaling a named event in your callback. Give it the exception info it needs with a memory-mapped file. The helper can do pretty much anything it wants when it sees the event signaled. Including showing a message, taking a minidump. And terminating the main process.
Which is exactly how the Microsoft WerFault helper works.
Hans Passant's answer about SetUnhandledExceptionFilter is on the right track. He also makes some good points about not being able to do too much within the callback because various parts of the process could be in an unstable state.
However, from the way the issue is described, it doesn't sound like you want to do anything except tell the system not to put up the normal crash dialog. In that case, it's easy and should be safe regardless of what parts of the process the crash may have affected.
Make a function something like this:
LONG WINAPI UnhandledExceptionCallback(PEXCEPTION_POINTERS pExceptPtrs)
{
if (IsDebuggerPresent())
// Allow normal crash handling, which means the debugger will take over.
return EXCEPTION_CONTINUE_SEARCH;
else
// Say we've handled it, so that the standard crash dialog is inhibited.
return EXCEPTION_EXECUTE_HANDLER;
}
And somewhere in your program (probably as early as possible) set the callback:
SetUnhandledExceptionFilter(UnhandledExceptionCallback);
That should do what you want - allow any crashes of that particular program to die silently.
However, there's something else to note about this: Any time you bring in 3rd-party components (DLLs, OCXs, etc) there is a risk that one of them may also call SetUnhandledExceptionFilter and thus replace your callback with their own. I once encountered an ActiveX control that would set its own callback when instantiated. And even worse, it failed to restore the original callback when it was destroyed. That seemed to be a bug in their code, but regardless I had to take extra steps to ensure that my desired callback was at least restored when it was supposed to be after their control was shutdown. So if you find this doesn't appear to work for you sometimes, even when you know you've set the callback correctly, then you may be encountering something similar.
I found myself in exactly this situation while developing a Delphi application. I found that I needed two things to reliably suppress the "app has stopped working" dialog box.
Calling SetErrorMode(SEM_NOGPFAULTERRORBOX);
suppresses the "app has stopped working" dialog box. But then Delphi's exception handler shows a message box with a runtime error message instead.
To suppress Delphi's exception handler I call SetUnhandledExceptionFilter
with a custom handler that terminates the process by calling Halt
.
So the skeleton for a Delphi client app that runs code prone to crashes becomes:
function HaltOnException(const ExceptionInfo: TExceptionPointers): Longint; stdcall;
begin
Halt;
Result := 1; // Suppress compiler warning
end;
begin
SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(@HaltOnException);
try
DoSomethingThatMightCrash;
except
on E: Exception do
TellServerWeFailed(E.Message);
end;
end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With