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.
views:
370answers:
5Follow the steps in this article to control this behavior.
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.
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.