2009-11-08 7 views
6

Questa potrebbe non essere una domanda puramente relativa alla programmazione, ma ci si imbatte spesso durante lo sviluppo. Quando la mia app si arresta in modo anomalo e scelgo di ucciderlo, Windows genera automaticamente una finestra di dialogo "Verifica di una soluzione ...". Quando premo il pulsante di annullamento su quello ottengo un'altra finestra di dialogo che dice "Riavvio del programma ..." C'è un modo per prevenire questo comportamento? Quando interrompo un'app, preferirei se venisse ucciso silenziosamente. Sto usando Windows 7 se la piattaforma è importante.Windows - Impedisci arresti anomali del sistema "Verifica la presenza di una soluzione ..." e "Riavvio del programma ..."

risposta

4

Seguire i passaggi in this article per controllare questo comportamento.

+0

Ottima soluzione, rimuove il WER per tutte le app. –

2

Anche se Microsoft consiglia di utilizzare un'API di sostituzione più recente disponibile solo su Windows Vista e versioni successive, v'è un'API che funziona per tutte le versioni di Windows da XP in poi: AddERExcludedApplication(). Questa funzione prende il nome del modulo senza informazioni sul percorso (ad es. "Myprogram.exe") per il quale la segnalazione degli errori deve essere disabilitata.

Il nuovo metodo disponibile solo per Windows Vista e versioni successive è per chiamare WerAddExcludedApplication() function. Questa API consente di specificare se deve modificare l'hive del registro HKEY_CURRENT_USER o l'hive del registro HKEY_LOCAL_MACHINE. Assicurarsi di impostare questo per il HKCU se il set HKLM fallisce, come ad esempio:

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

a ridurre ulteriormente l'esecuzione dei componenti WER, imeplement un filtro eccezione non gestita e passarlo: SetUnhandledExceptionFilter() function. Per evitare il WER, il filtro non deve mai restituire EXCEPTION_CONTINUE_SEARCH o EXCEPTION_EXECUTE_HANDLER.

Uno degli svantaggi dell'implementazione della funzione SetUnhandledExceptionFilter() è che interferisce con il debug del Just-in-time.

Hai detto che vuoi che l'app sia "silenziosamente uccisa". In tal 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); 
    /* ... */ 
} 

L'applicazione sparirà immediatamente in caso di eccezione non gestita. N.B., il codice di uscita da restituire è una questione di gusti.

+4

Un avvertimento ENORME: nessuno dovrebbe MAI usare SetUnhandledExceptionFilter nel codice di produzione. se si fa uso SetUnhandledExceptionFilter, assicurarsi che si chiama TerminateProcess nel filtro eccezione - altrimenti si sta andando a trasformare un incidente facilmente debuggable in una delle due cose: Se siete fortunati, si ottiene una corruzione della memoria sottile che sarà non causare problemi ai tuoi clienti. Se non sei fortunato, introduci un bug di sicurezza sfruttabile nella tua applicazione. –

+0

In realtà, il mio pensiero era installare un filtro che chiama FatalAppExit(). A proposito, ciao Larry! –

+0

@Larry, per WerAddExcludedApplication(), sai se questo richiede un nome di modulo piuttosto che un percorso completo, o viceversa? –

1

mi rendo conto che gli altri hanno risposto con modi per aggirare questo, ma ...

Non dimentichiamo che il modo migliore per proteggere contro questo è quello di scrivere un programma che non va in crash. :-) Non dovresti vedere questo se stai usando la memoria correttamente e non appendendo il thread della GUI.

Alterare il comportamento di un arresto anomalo dell'applicazione è un ottimo modo per introdurre bug sottili e mortali. Vedi anche this blog post di Microsoft Raymond Chen.

+0

E 'proprio di James Cadd per impedire a Microsoft di spiare il suo codice, indipendentemente dal fatto che i suoi crash di codice o un po' di MS dll lui chiama crash su 1 .% dei sistemi dei clienti –

+0

non credo che stanno a spiare il suo codice Tutte le segnalazioni di crash vengono inseriti nel loro sistema Winqual dove gli sviluppatori possono visualizzare segnalazioni di crash per le loro applicazioni:. http://en.wikipedia.org/ wiki/Winqual –

+0

Sì, tutti gli sviluppatori che possiedono certificati possono vedere i report per la propria applicazione Dove si afferma che i dipendenti Microsoft non possono guardare i report per applicazioni di terze parti? Non cercare quella clausola nell'utilizzo accordo - non è lì. –

Problemi correlati