2010-08-12 16 views
139

Sto usando un oggetto COM (MODI) dalla mia applicazione .net. Il metodo che sto chiamando genera un'eccezione System.AccessViolationException, che viene intercettata da Visual Studio. La cosa strana è che ho bloccato la mia chiamata in un try catch, che ha gestori per AccessViolationException, COMException e tutto il resto, ma quando Visual Studio (2010) intercetta l'AccessViolationException, il debugger si interrompe sulla chiamata al metodo (doc.OCR), e se passo attraverso, continua alla riga successiva invece di inserire il blocco catch. Inoltre, se eseguo questo all'esterno dello studio visivo, la mia applicazione si arresta in modo anomalo. Come posso gestire questa eccezione che viene generata all'interno dell'oggetto COM?Come gestire AccessViolationException

MODI.Document doc = new MODI.Document(); 
try 
{ 
    doc.Create(sFileName); 
    try 
    { 
     doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false); 
     sText = doc.Images[0].Layout.Text; 
    } 
    catch (System.AccessViolationException ex) 
    { 
     //MODI seems to get access violations for some reason, but is still able to return the OCR text. 
     sText = doc.Images[0].Layout.Text; 
    } 
    catch (System.Runtime.InteropServices.COMException ex) 
    { 
     //if no text exists, the engine throws an exception. 
     sText = ""; 
    } 
    catch 
    { 
     sText = ""; 
    } 

    if (sText != null) 
    { 
     sText = sText.Trim(); 
    } 
} 
finally 
{ 
    doc.Close(false); 

    //Cleanup routine, this is how we are able to delete files used by MODI. 
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc); 
    doc = null; 
    GC.WaitForPendingFinalizers(); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 

} 
+0

Hai provato a mettere un gestore 'Exception' in (temporaneamente!) Per intercettare tutte le eccezioni e vedere qual è l'eccezione * effettivamente *? – ChrisF

+2

@ChrisF - sì, vedi l'ultimo gestore di catch? Questo dovrebbe catturare tutto, inclusa l'eccezione e qualsiasi sottoclasse di eccezioni. Inoltre, Visual Studio riporta che l'eccezione è System.AccessViolationException – Jeremy

+0

D'oh - mancata, scusa. – ChrisF

risposta

239

In .NET 4.0, il runtime gestisce alcune eccezioni generate come errori di Windows Structured Error Handling (SEH) come indicatori di stato danneggiato. Queste Eccezioni di stato corrotte (CSE) non possono essere catturate dal codice gestito standard. Non entrerò nel perché o come è qui. Leggi questo articolo su CSE è nel .NET Framework 4.0:

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

Ma c'è una speranza. Ci sono alcuni modi per aggirare questo:

  1. Ricompilare come un assembly .NET 3.5 ed eseguirlo in. NET 4.0.

  2. aggiungere una riga al file di configurazione dell'applicazione sotto l'elemento di configurazione/runtime: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. decorare la modalità che si desidera per la cattura di queste eccezioni con l'attributo HandleProcessCorruptedStateExceptions. Vedi http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 per i dettagli.

Per maggiori riferimento: http://connect.microsoft.com/VisualStudio/feedback/details/557105/unable-to-catch-accessviolationexception

+43

HandleProcessCorruptedStateExceptions fa il trucco. – Jeremy

+7

'HandleProcessCorruptedStateExceptions' funziona per me in .Net 4.5. – deerchao

+1

Grazie, questo mi ha davvero aiutato. – FlyingMaverick

1

Si può provare a utilizzare AppDomain.UnhandledException e vedere se questo consente di prenderlo.

** EDIT *

Ecco alcune more information che potrebbe essere utile (è una lunga lettura).

+1

Provato AppDomain.UnhandledException, no luck, darà l'articolo in lettura ... – Jeremy

+1

Questa risposta non è più completa precisa a causa di cambiamenti nel framework .NET. Prima di 4.0 è corretto. Per sezione di AccessViolationException e try/catch blocchi in https://msdn.microsoft.com/en-us/library/system.accessviolationexception(v=vs.110).aspx – Tedford

11

Aggiungere il seguente nel file di configurazione, e sarà preso in blocco try catch. Parola di cautela ... cerca di evitare questa situazione, poiché ciò significa che sta accadendo un qualche tipo di violazione.

+0

Per coloro che usano C++/cli come dll, il codice dovrebbe essere aggiunto al progetto .exe superiore. – Felix

4

Compilato dalle risposte precedenti, ha funzionato per me, ha seguito i passaggi per catturarlo.

Passo # 1 - Aggiungere seguente frammento di config file di

<configuration> 
    <runtime> 
     <legacyCorruptedStateExceptionsPolicy enabled="true" /> 
    </runtime> 
</configuration> 

Passo # 2

Add -

[HandleProcessCorruptedStateExceptions] 

[SecurityCritical] 

sulla parte superiore della funzione che si sta legando intercettare l'eccezione

fonte: http://www.gisremotesensing.com/2017/03/catch-exception-attempted-to-read-or.html

+0

In base a https://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute(v=vs.110).aspx, SecurityCriticalAttribute è equivalente a una richiesta di collegamento per trust completo. Non penso che il problema descritto richieda una piena fiducia. – Jeremy

Problemi correlati