Pergunta

Estou usando um objeto COM (MODI) no meu aplicativo .NET. O método que estou chamando lança um sistema.AccessViolationException, que é interceptado pelo Visual Studio. O estranho é que eu envolvi minha chamada em uma tentativa, que tem manipuladores para AccessViolationException, Comexception e tudo mais, mas quando o Visual Studio (2010) intercepta a AccessViolationException, o depurador quebra na chamada do método (doc.ocr), E se eu passar, ele continuará para a próxima linha em vez de entrar no bloco de captura. Além disso, se eu executar isso fora do Visual Studio, meu aplicativo trava. Como posso lidar com essa exceção que é lançada dentro do objeto COM?

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();

}
Foi útil?

Solução

No .NET 4.0, o tempo de execução lida com certas exceções aumentadas como erros de manuseio de erros estruturados do Windows (SEH) como indicadores de estado corrompido. Essas exceções de estado corrompidas (CSE) não podem ser capturadas pelo seu código gerenciado padrão. Não vou entrar no porquê ou como está aqui. Leia este artigo sobre a CSE na estrutura .NET 4.0:

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

Mas há esperança. Existem algumas maneiras de contornar isso:

  1. Recompile como um conjunto .NET 3.5 e execute -o no .NET 4.0.

  2. Adicione uma linha ao arquivo de configuração do seu aplicativo no elemento de configuração/tempo de execução:<legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. Decore os métodos em que você deseja capturar essas exceções com o HandleProcessCorruptedStateExceptions atributo. Ver http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035 para detalhes.


EDITAR

Anteriormente, eu referenciei um post do fórum Para detalhes adicionais. Mas como a Microsoft Connect foi aposentada, aqui estão os detalhes adicionais, caso você esteja interessado:

De Gaurav Khanna, um desenvolvedor da equipe da Microsoft CLR

Esse comportamento é por design devido a um recurso do CLR 4.0 chamado exceções de estado corrompido. Simplificando, o código gerenciado não deve tentar capturar exceções que indicam o estado do processo corrompido e o AV é um deles.

Ele então continua referenciando a documentação no HandleProcessCorruptedStateExceptionAttribute e o artigo acima. Basta dizer que definitivamente vale a pena ler se você está pensando em pegar esses tipos de exceções.

Outras dicas

Adicione o seguinte no arquivo de configuração e ele será capturado no BLOCO TENT CATCH. Palavra de cautela ... tente evitar essa situação, pois isso significa que algum tipo de violação está acontecendo.

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

Compilado a partir de respostas acima, trabalhou para mim, fez as seguintes etapas para pegá -lo.

Etapa 1 - Adicione o seguinte snippet ao arquivo de configuração

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

Passo 2

Adicionar -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]

No topo da função, você está vinculando a exceção

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

Você pode tentar usar AppDomain.UnHandledException E veja se isso permite pegá -lo.

**EDITAR*

Aqui está alguns Mais Informações Isso pode ser útil (é uma leitura longa).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top