2010-08-12 79 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