2009-11-08 11 views
6

Puede que esta no sea una pregunta puramente relacionada con la programación, pero me topa con esto durante el desarrollo. Cuando mi aplicación falla y elijo matarla, Windows automáticamente lanza un cuadro de diálogo "Buscando una solución ...". Cuando pulso el botón de cancelar, aparece otro cuadro de diálogo que dice "Reiniciar el programa ..." ¿Hay alguna manera de evitar este comportamiento? Cuando detengo una aplicación, prefiero que la maten silenciosamente. Estoy usando Windows 7 si la plataforma es importante.Windows - Prevenir bloqueos "Buscando una solución ..." y "Reiniciar el programa ..."

Respuesta

4

Siga los pasos en this article para controlar este comportamiento.

+0

Gran solución, elimina WER para todas las aplicaciones. –

2

Aunque Microsoft recomienda el uso de una nueva API más reciente disponible sólo en Windows Vista y más adelante, hay una API cuales funciona para todas las versiones de Windows desde XP en adelante: AddERExcludedApplication(). Esta función toma el nombre del módulo sin información de ruta (por ejemplo, "myprogram.exe") para la cual se debe deshabilitar el informe de errores.

El nuevo método disponible solo para Windows Vista y posterior es llamar al WerAddExcludedApplication() function. Esta API le permite especificar si debe cambiar la sección de registro HKEY_CURRENT_USER o la sección de registro HKEY_LOCAL_MACHINE. Asegúrese de ajustar esto para el HKCU si el conjunto HKLM falla, tales como:

 
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; 
} 

para reducir aún más la ejecución de los componentes WER, imeplement un filtro de excepción no controlada y pasarlo a: SetUnhandledExceptionFilter() function. Para derivar WER, su filtro nunca debe devolver EXCEPTION_CONTINUE_SEARCH o EXCEPTION_EXECUTE_HANDLER.

Uno de los inconvenientes de implementar la función SetUnhandledExceptionFilter() es que interfiere con la eliminación de errores Just-in-time.

Menciona que desea que la aplicación sea "silenciosamente asesinada". En ese caso:

 

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); 
    /* ... */ 
} 

Causará que la aplicación se desvanezca inmediatamente ante una excepción no controlada. N.B., el código de salida para regresar es una cuestión de gusto.

+4

Advertencia ENORME: Nadie DEBERÍA utilizar el filtro SetUnhandledExceptionFilter en el código de producción. Si utiliza SetUnhandledExceptionFilter, asegúrese de llamar a TerminateProcess en su filtro de excepciones; de lo contrario, podrá convertir una falla fácilmente depurable en una de dos cosas: si tiene suerte, obtendrá una corrupción de memoria sutil que sin fin de problemas para sus clientes. Si no tienes suerte, introducirás un error de seguridad explotable en tu aplicación. –

+0

En realidad, pensé en instalar un filtro que llama a FatalAppExit(). ¡Por cierto, hola Larry! –

+0

@Larry, para WerAddExcludedApplication(), ¿sabe si eso requiere un nombre de módulo en lugar de una ruta completa, o viceversa? –

1

que se dan cuenta de que otros han respondido con formas de solucionar esto, pero ...

No olvidemos que la mejor manera de protegerse contra esto es escribir un programa que no se bloquee. :-) No debería ver esto si está utilizando la memoria correctamente y no está colgando el hilo de la GUI.

Alterar el comportamiento de un bloqueo de aplicación es una excelente manera de introducir errores sutiles y mortales. Consulte también this blog post de Raymond Chen de Microsoft.

+0

Es el derecho de James Cadd evitar que Microsoft espíe su código, independientemente de si su código falla o algún dll de MS al que llama bloqueos en 1 % de los sistemas de los clientes. –

+0

No creo que estén espiando su código. Todos los informes de fallos se introducen en su sistema Winqual, donde los desarrolladores pueden ver los informes de fallas de sus aplicaciones: http://en.wikipedia.org/ wiki/Winqual –

+0

Sí, todos los desarrolladores que poseen certificados pueden ver los informes para su propia aplicación. ¿Dónde se indica que los empleados de Microsoft no pueden ver los informes para aplicaciones de terceros? No busque esa cláusula en el uso acuerdo - no está allí. –

Cuestiones relacionadas