如何检查IOException是否不够磁盘空间exceptiontypes?

如何检查IOException是否为“磁盘空间不足”exceptiontypes?

此刻,我检查消息是否匹配“磁盘空间不足”的信息,但是我知道如果操作系统语言不是英语,这将不起作用。

您需要检查HResult并针对ERROR_DISK_FULL(0x70)和ERROR_HANDLE_DISK_FULL(0x27) 进行HResults ,通过与0x80070000进行OR , 可以将其转换为HResults

对于.Net Framework 4.5及更高版本,您可以使用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; } 

对于较早的版本,可以使用Marshal.GetHRForException来取回HResult,但是这有重大的副作用,不build议使用 :

 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; } 

从MSDN文档:

请注意, GetHRForException方法设置当前线程的IErrorInfo 。 这可能会导致像ThrowExceptionForHR方法的方法,如果它被设置默认使用当前线程的IErrorInfo的方法意外的结果。

另请参见如何确定System.IO.IOException的HResult?

在.NET 4.5中, HResult属性获取器现在是Public,因此您不必再使用Marshal.GetHRForException (以及其副作用)。

http://msdn.microsoft.com/en-us/library/system.exception.hresult(v=vs.110).aspx states“从.NET Framework 4.5开始,HResult属性的setter受到保护,而其getter在以前的.NET Framework版本中,getter和setter都是受保护的“

所以你可以使用Justin的答案,但用ex.HResultreplaceMarshal.GetHRForException(ex)

好吧,这有点不好意思,但我们走了。

首先要做的是从exception中获取HResult 。 因为它是一个受保护的成员,所以我们需要一点反思来获得价值。 这里有一个扩展方法可以做到这一点:

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

现在,在你的捕获范围内,你可以得到HResult

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

从这里,你必须解释人权。 你需要这个链接 。

我们需要得到存储在值的第一个16位的ErrorCode ,所以这里有一些操作:

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

现在,请参阅系统错误代码列表,在这里我们是:

 ERROR_DISK_FULL 112 (0x70) 

所以testing它使用:

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

也许有一些“更高层次”的function来获得所有这些东西,但至less是有效的。

最简单的内联解决scheme(min .NET 4.5和C#6):

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

System.IOException有一些派生的exceptiontypes,但是没有一个派生types的声音像你的exception。 您可以查看exception的HResult或Data属性,也许这将有一个更具体的错误代码详细。 根据MSDN ,这些属性都是该exceptiontypes的一部分。 只要确保你尝试捕获特定的exceptiontypes,而不仅仅是基本的exceptiontypes。