visual valid net method generate example documentacion comment comentarios code c# .net exception-handling ioexception diskspace

c# - valid - ¿Cómo comprobar si IOException es el tipo No-Suficiente-Disco-Espacio-Excepción?



generate documentation c# (5)

¿Cómo puedo verificar si IOException es un tipo de excepción "No hay espacio suficiente en el disco"?

En este momento compruebo si el mensaje coincide con algo así como "No hay suficiente espacio en el disco", pero sé que esto no funcionará si el idioma del sistema operativo no es el inglés.


Bueno, es un poco hacky, pero aquí vamos.

Lo primero que debe hacer es obtener el HResult de la excepción. Como es un miembro protegido, necesitamos un poco de reflexión para obtener el valor. Aquí hay un método de extensión para hacer el truco:

public static class ExceptionExtensions { public static int HResultPublic(this Exception exception) { var hResult = exception.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(z => z.Name.Equals("HResult")).First(); return (int)hResult.GetValue(exception, null); } }

Ahora, en su alcance de captura, puede obtener el HResult :

catch (Exception ex) { int hResult = ex.HResultPublic(); }

A partir de aquí, deberá interpretar HResult. Necesitarás este enlace .

Necesitamos obtener el ErrorCode que está almacenado en los 16 primeros bits del valor, así que aquí hay una operación de bit:

int errorCode = (int)(hResult & 0x0000FFFF);

Ahora, consulte la lista de códigos de error del sistema y aquí estamos:

ERROR_DISK_FULL 112 (0x70)

Así que pruébelo usando:

switch (errorCode) { case 112: // Disk full }

Tal vez haya algunas funciones de "nivel superior" para obtener todo esto, pero al menos funciona.


En .NET 4.5, el getter de propiedad HResult ahora es Public, por lo que ya no tiene que usar Marshal.GetHRForException (junto con sus efectos secundarios).

http://msdn.microsoft.com/en-us/library/system.exception.hresult(v=vs.110).aspx states "Comenzando con .NET Framework 4.5, el setter de la propiedad HResult está protegido, mientras que su getter es público. En versiones anteriores de .NET Framework, tanto getter como setter están protegidos "

Entonces puede usar la respuesta de Justin, pero reemplace Marshal.GetHRForException(ex) con ex.HResult .


La solución en línea más simple (min .NET 4.5 y C # 6):

try { //... } catch (IOException ex) when ((ex.HResult & 0xFFFF) == 0x27 || (ex.HResult & 0xFFFF) == 0x70) { //... }


System.IOException tiene una serie de tipos de excepción derivados, sin embargo, ninguno de estos tipos derivados suena como su excepción. Puede ver la propiedad HResult o Data de la excepción, quizás esto tendrá un código de error más específico detallado. Según MSDN ambas propiedades forman parte de ese tipo de excepción. Solo asegúrese de intentar capturar el tipo de excepción específico, no solo el tipo de excepción base.


HResult verificar HResult y probar contra ERROR_DISK_FULL (0x70) y ERROR_HANDLE_DISK_FULL (0x27) , que se puede convertir a HResults al OR ''con 0x80070000 .

Para .Net Framework 4.5 y superior, puede usar la propiedad Exception.HResult :

static bool IsDiskFull(Exception ex) { const int HR_ERROR_HANDLE_DISK_FULL = unchecked((int)0x80070027); const int HR_ERROR_DISK_FULL = unchecked((int)0x80070070); return ex.HResult == HR_ERROR_HANDLE_DISK_FULL || ex.HResult == HR_ERROR_DISK_FULL; }

Para versiones anteriores, puede usar Marshal.GetHRForException para recuperar HResult, pero esto tiene importantes efectos secundarios y no se recomienda :

static bool IsDiskFull(Exception ex) { const int ERROR_HANDLE_DISK_FULL = 0x27; const int ERROR_DISK_FULL = 0x70; int win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF; return win32ErrorCode == ERROR_HANDLE_DISK_FULL || win32ErrorCode == ERROR_DISK_FULL; }

De la documentación de MSDN:

Tenga en cuenta que el método GetHRForException establece IErrorInfo del hilo actual. Esto puede causar resultados inesperados para métodos como los métodos ThrowExceptionForHR que usan de forma predeterminada el IErrorInfo del hilo actual si está configurado.

Consulte también ¿Cómo determino HResult para System.IO.IOException?