2010-08-12 78 views
139

我在我的.net应用程序中使用COM对象(MODI)。我正在调用的方法抛出一个System.AccessViolationException,它被Visual Studio拦截。奇怪的是,我已经把我的调用包装在try catch中,它具有处理AccessViolationException,COMException和其他所有事件的处理程序,但是当Visual Studio(2010)拦截AccessViolationException时,调试器会中断方法调用(doc.OCR),如果我经过,它会继续到下一行,而不是进入catch块。另外,如果我在Visual Studio之外运行,我的应用程序崩溃。我该如何处理在COM对象中引发的这个异常?如何处理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

您是否曾尝试在(临时!)中放置一个'Exception'处理程序来捕获所有异常并查看异常*实际*是什么? – ChrisF 2010-08-12 15:37:19

+2

@ChrisF - 是的,请参阅最后的catch处理程序?这应该捕获所有内容,包括Exception和Exception的任何子类。另外,Visual Studio报告这个异常是System.AccessViolationException – Jeremy 2010-08-12 15:38:55

+0

D'oh - 错过了,很抱歉。 – ChrisF 2010-08-12 15:47:25

回答

239

在.NET 4.0中,运行时处理某些作为Windows结构化错误处理(SEH)错误引发的异常,作为损坏状态的指示器。这些损坏的状态异常(CSE)不允许被标准托管代码捕获。我不会理解为什么或在这里如何。阅读这篇文章,关于CSE公司在.NET 4.0框架:

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

但有希望。有几种方法可以解决这个问题:

  1. 重新编译为.NET 3.5程序集并在.NET 4.0中运行它。

  2. 添加一行到应用程序的配置文件中的配置/运行元素: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. 装饰你想与HandleProcessCorruptedStateExceptions属性来捕获这些异常的方法。详情请参见http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

更多参考: http://connect.microsoft.com/VisualStudio/feedback/details/557105/unable-to-catch-accessviolationexception

+43

中的AccessViolationException和try/catch块的每个部分HandleProcessCorruptedStateExceptions都有效。 – Jeremy 2011-08-29 15:37:18

+7

HandleProcessCorruptedStateExceptions在.Net 4.5中适用于我。 – deerchao 2013-05-26 08:56:34

+1

谢谢,这真的有帮助。 – FlyingMaverick 2013-06-12 14:34:30

1

你可以尝试使用AppDomain.UnhandledException,看看是否让你抓住它。

**编辑*

下面是一些more information可能有用的(这是一个漫长的读取)。

+1

尝试AppDomain.UnhandledException,没有运气,会给文章读... – Jeremy 2010-08-12 20:05:50

+1

由于.NET框架的变化,此答案不再准确无误。在4.0之前,这是正确的。在https://msdn.microsoft.com/zh-cn/library/system.accessviolationexception(v=vs.110).aspx – Tedford 2017-08-11 17:52:19

11

添加在配置文件中的以下内容,将在try catch块被捕获。 谨慎的话...尽量避免这种情况,因为这意味着某种违规行为正在发生。

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

对于那些使用C++/cli作为dll的应用程序,应该将代码添加到顶级的.exe项目中。 – Felix 2017-06-20 02:34:03

4

从上面的答案编译,为我工作,做了以下步骤来捕捉它。

第1步 - 添加下面的代码片段到配置文件

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

步骤#2

添加 -

[HandleProcessCorruptedStateExceptions] 

[SecurityCritical] 

在功能上你绑捕获异常

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

+0

根据https://msdn.microsoft.com/en-us/library/system.security.securitycriticalattribute(v=vs.110).aspx,SecurityCriticalAttribute相当于完全信任的链接要求。我认为所描述的问题不一定要求完全信任。 – Jeremy 2017-03-23 18:59:45