/// <summary> /// Turns HRESULT errors into the appropriate exception (that maps with existing .NET behavior as much as possible). /// There are additional IOException derived errors for ease of client error handling. /// </summary> public static Exception GetIoExceptionForHResult(HRESULT hr, string path = null) { string message = path == null ? $"{HResultToString(hr)}" : $"{HResultToString(hr)} '{path}'"; switch (hr) { case HRESULT.E_ACCESSDENIED: return(new UnauthorizedAccessException(message)); case HRESULT.E_INVALIDARG: return(new ArgumentException(message)); default: if (ErrorMacros.HRESULT_FACILITY(hr) == Facility.WIN32) { return(WindowsErrorToException((WindowsError)ErrorMacros.HRESULT_CODE(hr), message, path)); } else { return(new IOException(message, (int)hr)); } } }
/// <summary> /// Try to get the string for an HRESULT /// </summary> public static string HResultToString(HRESULT hr) { string message; if (ErrorMacros.HRESULT_FACILITY(hr) == Facility.WIN32) { // Win32 Error, extract the code message = ErrorMethods.FormatMessage( messageId: (uint)ErrorMacros.HRESULT_CODE(hr), source: IntPtr.Zero, flags: FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM); } else { // Hope that we get a rational IErrorInfo Exception exception = Marshal.GetExceptionForHR((int)hr); message = exception.Message; } return($"HRESULT {(int)hr:D} [0x{(int)hr:X}]: {message}"); }