En el código C#, ¿puede capturar una excepción nativa arrojada desde las profundidades de una biblioteca no administrada? Si es así, ¿tiene que hacer algo diferente para atraparlo o lo intenta de manera estándar ... atraparlo?¿Se puede capturar una excepción nativa en el código C#?
Respuesta
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);
}
}
}
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.
No se puede detectar un StackOverflow o OutOfMemoryException aunque, no importa qué, ¿correcto? – core
esos son errores que terminan, que detienen la aplicación, entonces sí, no puedes trabajar con ellos. –
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. –
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.
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 –
realmente? ¿Para qué era? –
en realidad no lo sé. –
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
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.
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
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
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
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.
- En el caso de un código de error SEH sabido que mapeará a la excepción de .NET apropiado (es decir OutOfMemoryException)
- 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.
* 'Windows implementa excepciones de C++ sobre SEH' *: ¿esto parece ser cierto solo para VC? – Wolf
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.
- 1. No se puede capturar la excepción C++ utilizando catch (...)
- 2. No se puede detectar la excepción nativa en el código administrado
- 3. WCF/C# No se puede capturar EndpointNotFoundException
- 4. ¿Por qué no se puede capturar la excepción interna?
- 5. ¿Se puede capturar una excepción por el tipo de operador de conversión?
- 6. java: no se puede volver a lanzar una excepción: no controlada tipo de excepción Excepción
- 7. ¿Cómo se está ejecutando el código después de una excepción?
- 8. capturar una excepción sin hacer nada en la captura
- 9. Cuándo capturar RuntimeExceptions en el código?
- 10. ¿Qué se puede lograr en una aplicación móvil nativa que no se puede hacer en una aplicación web HTML5?
- 11. C: ¿Cómo se simula una 'excepción'?
- 12. Capturar excepción personalizada del servicio web ASMX
- 13. ¿Cómo se puede inspeccionar mediante programación el seguimiento de la pila de una excepción en Python?
- 14. ¿Cómo puede el código en un bloque "try ... catch" arrojar una excepción no controlada?
- 15. lanzar una excepción en el hilo C#
- 16. ¿Hay alguna función PHP nativa que arroje una Excepción incorporada?
- 17. ¿Cómo crear una biblioteca nativa de C++ en Android?
- 18. ¿Puede Monitor.Enter lanzar una excepción?
- 19. Llamar a una devolución de llamada nativa desde el código .NET administrado (al cargar el código administrado usando COM)
- 20. Android: capturar el retorno de una actividad
- 21. Cómo capturar métricas de código en Xcode?
- 22. ¿Por qué capturar una excepción como referencia-a-const?
- 23. C++, ignora la excepción y continúa el código?
- 24. Manejando una excepción nula C#
- 25. ¿Se puede optimizar este código?
- 26. ¿Puedo hacer una aplicación en C++ bastante nativa con Android?
- 27. Marshal.GetActiveObject() lanza una excepción MK_E_UNAVAILABLE en C#
- 28. No se puede detectar la excepción causada por C dll llamada a través de PInvoke
- 29. ¿Cómo puedo depurar una excepción no controlada en el código administrado cuando se llama desde COM?
- 30. Localizar el número de línea donde se produce una excepción en el código Python
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. –