This may not be a purely programming related question, but I come across this often during development. When my app crashes and I choose to kill it, Windows automatically throws up a "Checking for a solution..." dialog box. When I hit the cancel button on that I get another dialog box that says "Restarting the program..." Is there a way to prevent this behavior? When I stop an app I'd prefer if it were silently killed. I'm using Windows 7 if the platform is important.
-
Follow the steps in [this article](http://www.sevenforums.com/tutorials/4550-problem-reports-solutions-change-check-solutions-settings.html) to control this behavior. – Traveling Tech Guy Nov 08 '09 at 23:37
-
Great solution, removes WER for all apps. – James Cadd Nov 09 '09 at 14:59
4 Answers
Although Microsoft recommends using a newer replacement API available only on Windows Vista and later, there is an API which works for all versions of Windows from XP onward: AddERExcludedApplication(). This function takes the module name without path information (e.g., "myprogram.exe") for which error reporting is to be disabled.
The new method available only Windows Vista and later is to call WerAddExcludedApplication() function. This API allows you to specify whether it should change the HKEY_CURRENT_USER registry hive, or the HKEY_LOCAL_MACHINE registry hive. Be sure to set this for the HKCU if the HKLM set fails, such as:
typedef BOOL (*ADD_MER_EXCLUDED_APP_XP) (PCWSTR); typedef BOOL (*ADD_MER_EXCLUDED_APP_VISTA) (PCWSTR, BOOL); bool disable_microsoft_error_reporting(PCWSTR wz_app) { const WCHAR * const WZ_MER_DLL_XP = L"faultrep.dll"; const char * const SZ_MER_PROC_XP = "AddERExcludedApplicationW"; const WCHAR * const WZ_MER_DLL_VISTA = L"wer.dll"; const char * const SZ_MER_PROC_VISTA = "WerAddExcludedApplicationW"; const int WER_EXCLUDE_FOR_ALL_USERS = TRUE; const int WER_EXCLUDE_FOR_THIS_USER = FALSE; HANDLE hlib_error_reports_xp = NULL; HANDLE hlib_error_reports_vista = NULL; ADD_MER_EXCLUDED_APP_XP add_mer_excluded_app_xp = NULL; ADD_MER_EXCLUDED_APP_VISTA add_mer_excluded_app_vista = NULL; bool success = false; // First, attempt the API that has been around since XP. hlib_error_reports_xp = LoadLibrary(WZ_MER_DLL_XP); if (hlib_error_reports_xp) { add_mer_excluded_app_xp = (ADD_MER_EXCLUDED_APP_XP)GetProcAddress(hlib_error_reports_xp, SZ_MER_PROC_XP); if (add_mer_excluded_app_xp) success = add_mer_excluded_app_xp(wz_app); FreeLibrary(hlib_error_reports_xp); hlib_error_reports_xp = NULL; add_mer_excluded_app_xp = NULL; if (success) return true; } // That did not succeed. Attempt the Vista API. hlib_error_reports_vista = LoadLibrary(WZ_MER_DLL_VISTA); if (hlib_error_reports_vista) { add_mer_excluded_app_vista = (ADD_MER_EXCLUDED_APP_VISTA)GetProcAddress(hlib_error_reports_vista, SZ_MER_PROC_VISTA); if (add_mer_excluded_app_vista) { success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_ALL_USERS)); if (!success) success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_THIS_USER)); } FreeLibrary(hlib_error_reports_vista); hlib_error_reports_vista = NULL; add_mer_excluded_app_vista = NULL; if (success) return true; } // Nothing worked. Fail. return false; }
To further curtail the execution of the WER components, imeplement an unhandled exception filter and pass it to: SetUnhandledExceptionFilter() function. To shunt WER, your filter must never return EXCEPTION_CONTINUE_SEARCH
or EXCEPTION_EXECUTE_HANDLER
.
One of the drawbacks of implementing the SetUnhandledExceptionFilter()
function is that it interferes with Just-in-time debugging.
You mention you want the app to be "silently killed." In that case:
LONG WINAPI global_exception_filter(struct _EXCEPTION_POINTERS *exception_info) { ExitProcess(0xDEDD000D); } int WINAPI WinMain( HINSTANCE _hinstance, HINSTANCE hinstance_prev, LPSTR sz_cmd_line, int cmd_show ) { SetUnhandledExceptionFilter(global_exception_filter); /* ... */ }
Will cause the application to immediately vanish upon unhandled exception. N.B., the exit code to return is a matter of taste.

- 18,667
- 3
- 39
- 62
-
4One HUGE caveat: Nobody should EVER use SetUnhandledExceptionFilter in production code. If you DO use SetUnhandledExceptionFilter, make sure that you call TerminateProcess in your exception filter - otherwise you're going to turn an easily debuggable crash into one of two things: If you're lucky, you get a subtle memory corruption that will cause no ends of trouble for your customers. If you're not lucky, you'll introduce an exploitable security bug in your application. – Larry Osterman Nov 09 '09 at 01:16
-
Actually, my thought was install a filter which calls FatalAppExit(). BTW, hi Larry! – Heath Hunnicutt Nov 09 '09 at 01:58
-
@Larry, for WerAddExcludedApplication(), do you know if that requires a module name rather than a complete path, or vice versa? – Heath Hunnicutt Nov 09 '09 at 02:01
-
@Heath: Unfortunately I do't know. Probably a full path if I had to guess. – Larry Osterman Nov 09 '09 at 03:15
-
Don't know why (and don't much care as its not used) but global_exception_filter wouldn't compile for me until I removed the name of the pointer, exception_info. – Thomas Sep 07 '10 at 15:57
-
I tried this in Python 2.7 (via ctypes) on Win7 and while the WerAddExcluded call reports success, the crashes still pop up the dialog. :( I was hoping to add an exception in a script, start the app, and then remove it when the application shut down. (The WerRemoveExcluded call fails with an undocumented error code (and it doesn't appear in WinError.h and Google shows it only in relation to Windows Update, getting it from WU means you need to reinstall Windows.) – dash-tom-bang Dec 12 '12 at 19:11
I realize that others have answered with ways to work around this, but...
Let's not forget that the best way to protect against this is to write a program that doesn't crash. :-) You shouldn't be seeing this if you are using memory correctly and not hanging the GUI thread.
Altering the behavior of an application crash is a great way to introduce subtle and deadly bugs. See also this blog post from Microsoft's Raymond Chen.

- 39,039
- 2
- 53
- 68
-
It's James Cadd's right to prevent Microsoft from spying on his code, regardless of whether his code crashes or some MS dll he calls crashes on 1% of customers' systems. – Heath Hunnicutt Nov 09 '09 at 01:59
-
I don't think they're spying on his code. All the crash reports get fed into their Winqual system where devs can see crash reports for their applications: http://en.wikipedia.org/wiki/Winqual – Luke Quinane Nov 09 '09 at 03:08
-
Yes, all devs who own certificates can see the reports for their own application. Where is it stated that Microsoft employees cannot look at the reports for 3rd-party applications? Don't search for that clause in the usage agreement -- it isn't there. – Heath Hunnicutt Nov 09 '09 at 05:23
-
To be honest, it's Visual Studio 2010 beta 2 that's doing a fair amount of crashing - I'll take some of the blame since it's my code running in the designer ;) – James Cadd Nov 09 '09 at 14:26
-
In my particular usage/need case it's a crappy third party application that crashes. I just want to be able to restart it without being physically present at the console. My special tweak is that I don't want to disable error handling or the debugger prompt globally but it seems that I have to as I do not have source code to the application to install a new crash handler into it (otherwise I'd just put a try/catch around everything in main() and be done with it). – dash-tom-bang Dec 12 '12 at 19:05