2008-09-29 20 views

Respuesta

31

Puede utilizar Win32Exception y utilizar su Propiedad NativeErrorCode para manejarlo apropiadamente.

// http://support.microsoft.com/kb/186550 
const int ERROR_FILE_NOT_FOUND = 2; 
const int ERROR_ACCESS_DENIED = 5; 
const int ERROR_NO_APP_ASSOCIATED = 1155; 

void OpenFile(string filePath) 
{ 
    Process process = new Process(); 

    try 
    { 
     // Calls native application registered for the file type 
     // This may throw native exception 
     process.StartInfo.FileName = filePath; 
     process.StartInfo.Verb = "Open"; 
     process.StartInfo.CreateNoWindow = true; 
     process.Start(); 
    } 
    catch (Win32Exception e) 
    { 
     if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND || 
      e.NativeErrorCode == ERROR_ACCESS_DENIED || 
      e.NativeErrorCode == ERROR_NO_APP_ASSOCIATED) 
     { 
      MessageBox.Show(this, e.Message, "Error", 
        MessageBoxButtons.OK, 
        MessageBoxIcon.Exclamation); 
     } 
    } 
} 
+6

Creo que esto no es automático, sino que solo se lanza cuando usa una firma P/Invocar que lo especifica. Y se basa en un código de error Win32, no en una excepción Win32. –

0

Si utiliza un

try 
{ 

} 
catch(Exception ex) 
{ 

} 

Se captura todas las excepciones, dependiendo de cómo se llama a las bibliotecas externas que podría recibir una excepción relacionada com que encapsula el error pero será detectar el error.

+0

No se puede detectar un StackOverflow o OutOfMemoryException aunque, no importa qué, ¿correcto? – core

+0

esos son errores que terminan, que detienen la aplicación, entonces sí, no puedes trabajar con ellos. –

+7

Esto no es del todo correcto, esto captará todas las excepciones que cumplen con CLS. C++/CLI y MC++ son ambos lenguajes capaces de lanzar excepciones que no cumplen con CLS. –

9

La capa de interoperabilidad entre C# y el código nativo convertirá la excepción en una forma administrada, permitiendo que sea capturada por su código C#. A partir de .NET 2.0, catch (Exception) debería detectar cualquier cosa que no sea un error irrecuperable.

+3

En .NET 1.x, es posible lanzar una excepción que no se deriva de la clase Exception, pero esta capacidad está desactivado por defecto en 2.0 –

+1

realmente? ¿Para qué era? –

+0

en realidad no lo sé. –

0

Una captura de prueba estándar debería hacer el truco, creo.

me encuentro con un problema similar con una excepción System.data lanzar una excepción SQLClient que era no detectada, la adición de un try..catch en mi código resolvieron el problema en el caso

5

En algún lugar usando un .NET Reflector he visto el siguiente código:

try { 
    ... 
} catch(Exception e) { 
    ... 
} catch { 
    ... 
} 

Hmm, C# no permite lanzar una excepción, no deriva de la clase System.Exception. Y, por lo que sé, cualquier cautch de excepción por parte del marshaller de interoperabilidad está envuelto por la clase de excepción que hereda la excepción System.Exception.

Así que mi pregunta es si es posible detectar una excepción que no sea una System.Exception.

+1

Es posible emitir o crear IL que arroje un objeto arbitrario. El compilador de C# no te permitirá hacerlo, pero otros compiladores pueden, o como dije, puedes emitir directamente el IL. Una instrucción catch sin tipo capturará objetos arbitrarios, así como objetos que heredan Exception. – technophile

16

La captura sin() atrapará las excepciones que no cumplen con CLS, incluidas las excepciones nativas.

try 
{ 

} 
catch 
{ 

} 

Ver la siguiente regla de FxCop para obtener más información http://msdn.microsoft.com/en-gb/bb264489.aspx

+7

Sí, esto es cierto. Acabo de descubrirlo yo mismo después de unas horas particularmente molestas al comparar los archivos de registro y el código y pensar que lo estaba perdiendo. Sin embargo, la siguiente pregunta obvia es, ¿se puede determinar el tipo de excepción nativa desde dentro del bloque catch vacío? ¿Puede registrar algo útil para identificar el origen de la excepción? – Tyson

4

Esto depende de qué tipo de excepción nativa que está hablando. Si se refiere a una excepción SEH, entonces el CLR hará una de dos cosas.

  1. En el caso de un código de error SEH sabido que mapeará a la excepción de .NET apropiado (es decir OutOfMemoryException)
  2. En el caso de un no-representable (E_FAIL) o código desconocido se acaba de lanzar una instancia de SEHException.

Ambos quedarán atrapados con un simple bloqueo "catch (Exception)".

El otro tipo de excepción nativa que puede cruzar el límite nativo/administrado son las excepciones de C++. No estoy seguro de cómo se asignan/manejan. Supongo que, dado que Windows implementa las excepciones de C++ sobre SEH, solo se asignan de la misma manera.

+0

* 'Windows implementa excepciones de C++ sobre SEH' *: ¿esto parece ser cierto solo para VC? – Wolf

3

Casi, pero no del todo.Obtendrá la excepción con

try 
{ 
    ... 
} 
catch (Exception e) 
{ 
    ... 
} 

pero todavía tendrá problemas potenciales. De acuerdo con MSDN, con el fin de asegurar los destructores de excepción se llama usted tendría que ponerse como:

try 
{ 
    ... 
} 
catch 
{ 
    ... 
} 

Ésta es la única manera de asegurar un destructor excepción se llama (aunque no estoy seguro de por qué). Pero eso te deja con la compensación de la fuerza bruta frente a una posible fuga de memoria.

Por cierto, si utiliza el enfoque (Excepción e), debe conocer los diferentes tipos de excepciones que puede encontrar. RuntimeWrappedException es lo que se asignará a cualquier tipo gestionado que no sea de excepción (para los lenguajes que pueden lanzar una cadena), y otros se asignarán, como OutOfMemoryException y AccessViolationException. COM Interop HRESULTS o excepciones que no sean E___FAIL se correlacionarán con COMException, y finalmente al final tendrá SEHException para E_FAIL o cualquier otra excepción no asignada.

¿Qué debes hacer? La mejor opción es no arrojar excepciones de su código no administrado. Hah. Realmente, si tiene una opción, ponga barreras y fallas que hagan que la elección sea peor, una posibilidad de pérdida de memoria durante el manejo de excepciones o no saber de qué tipo es su excepción.

Cuestiones relacionadas