Domanda

Ho un'applicazione MFC compilata con /clr e sto cercando di implementare un gestore finale per eccezioni gestite altrimenti non rilevate.Per le eccezioni native, override CWinApp::ProcessWndProcException lavori.

I due eventi suggeriti in Jeff's Articolo di CodeProject,Application.ThreadException E AppDomain.CurrentDomain.UnhandledException, non vengono sollevati.

Qualcuno può suggerire un modo per fornire un gestore di eccezioni gestite finali per un eseguibile misto?


Aggiornamento:

Sembra che questi gestori di eccezioni vengano attivati ​​solo a valle di Application.Run o simile (esiste un tipo di thread di lavoro, non ricordo il nome.) Se vuoi catturare veramente a livello globale un'eccezione gestita, devi installare un filtro SEH.Non otterrai un System.Exception e se vuoi uno stack di chiamate dovrai lanciare il tuo deambulatore.

In una domanda del forum MSDN su questo argomento è stato suggerito di sovrascrivere un punto di livello sufficientemente basso del thread MFC principale in un try ... catch (Exception^).Ad esempio, CWinApp::Run.Questa potrebbe essere una buona soluzione, ma non ho esaminato alcuna implicazione in termini di prestazioni o stabilità.Avrai la possibilità di accedere con uno stack di chiamate prima di eseguire il salvataggio e potrai evitare il comportamento predefinito delle eccezioni non gestite di Windows.

È stato utile?

Soluzione

Dando un'occhiata su Internet, scoprirai che è necessario installare un filtro per fare in modo che le eccezioni non gestite passino i filtri nel loro percorso verso il tuo AppDomain.Da Filtri CLR e eccezioni non gestite:

Il CLR si basa sul meccanismo di filtro delle eccezioni non gestite SEH per individuare le eccezioni non gestite.

Altri suggerimenti

L'uso di questi due gestori di eccezioni dovrebbe funzionare.

Perché dovrebbe?"

Gli eventi non vengono generati utilizzando quanto segue:

extern "C" void wWinMainCRTStartup();

// managed entry point
[System::STAThread]
int managedEntry( void )
{
    FinalExceptionHandler^ handler = gcnew FinalExceptionHandler();

    Application::ThreadException += gcnew System::Threading::ThreadExceptionEventHandler(
                                        handler,
                                        &FinalExceptionHandler::OnThreadException);

    AppDomain::CurrentDomain->UnhandledException += gcnew UnhandledExceptionEventHandler(
                                                        handler,
                                                        &FinalExceptionHandler::OnAppDomainException);

    wWinMainCRTStartup();

    return 0;
}

// final thread exception handler implementation
void FinalExceptionHandler::OnThreadException( Object^ /* sender */, System::Threading::ThreadExceptionEventArgs^ t )
{
    LogWrapper::log->Error( "Unhandled managed thread exception.", t->Exception );
}

// final appdomain exception handler implementation
void FinalExceptionHandler::OnAppDomainException(System::Object ^, UnhandledExceptionEventArgs ^args)
{
    LogWrapper::log->Error( "Unhandled managed appdomain exception.", (Exception^)(args->ExceptionObject) );
}

BOOL CMyApp::InitInstance()
{
    throw gcnew Exception("test unhandled");
    return TRUE;
}

L'uso di questi due gestori di eccezioni dovrebbe funzionare.Sei sicuro di averli aggiunti in un posto dove verranno richiamati e impostati correttamente (ad esempio, nel file dell'applicazione gestito punto di ingresso: ne hai inserito uno, vero?)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top