Практическое руководство. Сопоставление значений HRESULT и исключений

Методы COM сообщают об ошибках, возвращая значения HRESULT. Методы .NET в этом случае вызывают исключения. Среда выполнения обеспечивает сопоставление этих двух элементов. Каждый класс платформы .NET Framework сопоставляется со значением HRESULT.

Соответствующие значения HRESULT задаются определяемыми пользователем классами исключений. Эти классы исключений могут динамически изменять объект HRESULT, возвращаемый при создании исключения, задав HResult поле для объекта исключения. Дополнительные сведения об исключении предоставляются клиенту через IErrorInfo интерфейс, который реализуется в объекте .NET в неуправляемом процессе.

Если вы создаете класс, расширяющийся System.Exception, необходимо задать поле HRESULT во время строительства. В противном случае значение HRESULT будет присваиваться базовым классом. Чтобы сопоставить новые классы исключений с существующим значением HRESULT, укажите значение в конструкторе исключения.

Обратите внимание, что среда выполнения в некоторых случаях будет игнорировать значение HRESULT, если в потоке присутствует IErrorInfo. Это возможно в тех случаях, когда HRESULT и IErrorInfo представляют разные ошибки.

Создание нового класса исключения и его сопоставление со значением HRESULT

  1. В следующем коде создается новый класс исключения NoAccessException, который сопоставляется со значением HRESULT E_ACCESSDENIED.

    Class NoAccessException : public ApplicationException
    {
        NoAccessException () {
        HResult = E_ACCESSDENIED;
    }
    }
    CMyClass::MethodThatThrows
    {
    throw new NoAccessException();
    }
    

На любом языке программирования могут встречаться программы, в которых одновременно используется управляемый и неуправляемый код. Например, пользовательский маршаллировщик в следующем примере кода использует Marshal.ThrowExceptionForHR(int HResult) метод для создания исключения с определенным значением HRESULT. Этот метод выполняет поиск значения HRESULT и создает исключение соответствующего типа. Например, HRESULT в следующем фрагменте кода создает ArgumentException.

CMyClass::MethodThatThrows
{
    Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}

В следующей таблице приводится общий перечень сопоставлений значений HRESULT с соответствующими классами исключений в .NET. Значения HRESULT без явных сопоставлений сопоставляются с COMException. Актуальные сведения о сопоставлении представлены в репозитории среды выполнения/dotnet.

HRESULT Исключение .NET
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENT или E_INVALIDARG ArgumentException
COR_E_ARGUMENTOUTOFRANGE ArgumentOutOfRangeException
COR_E_ARITHMETIC or ERROR_ARITHMETIC_OVERFLOW ArithmeticException
COR_E_ARRAYTYPEMISMATCH ArrayTypeMismatchException
COR_E_BADIMAGEFORMAT or ERROR_BAD_FORMAT BadImageFormatException
COR_E_DIRECTORYNOTFOUND or ERROR_PATH_NOT_FOUND DirectoryNotFoundException
COR_E_DIVIDEBYZERO DivideByZeroException
COR_E_DUPLICATEWAITOBJECT DuplicateWaitObjectException
COR_E_ENDOFSTREAM EndOfStreamException
COR_E_ENTRYPOINTNOTFOUND EntryPointNotFoundException
COR_E_EXCEPTION Exception
COR_E_EXECUTIONENGINE ExecutionEngineException
COR_E_FIELDACCESS FieldAccessException
COR_E_FILENOTFOUND or ERROR_FILE_NOT_FOUND FileNotFoundException
COR_E_FORMAT FormatException
COR_E_INDEXOUTOFRANGE IndexOutOfRangeException
COR_E_INVALIDCAST or E_NOINTERFACE InvalidCastException
COR_E_INVALIDFILTERCRITERIA InvalidFilterCriteriaException
COR_E_INVALIDOPERATION InvalidOperationException
COR_E_IO IOException
COR_E_MEMBERACCESS AccessException
COR_E_METHODACCESS MethodAccessException
COR_E_MISSINGFIELD MissingFieldException
COR_E_MISSINGMANIFESTRESOURCE MissingManifestResourceException
COR_E_MISSINGMEMBER MissingMemberException
COR_E_MISSINGMETHOD MissingMethodException
COR_E_NOTFINITENUMBER NotFiniteNumberException
E_NOTIMPL NotImplementedException
COR_E_NOTSUPPORTED NotSupportedException
COR_E_NULLREFERENCE orE_POINTER NullReferenceException
COR_E_OUTOFMEMORY or

E_OUTOFMEMORY
OutOfMemoryException
COR_E_OVERFLOW OverflowException
COR_E_PATHTOOLONG or ERROR_FILENAME_EXCED_RANGE PathTooLongException
COR_E_RANK RankException
COR_E_REFLECTIONTYPELOAD ReflectionTypeLoadException
COR_E_SECURITY SecurityException
COR_E_SERIALIZATION SerializationException
COR_E_STACKOVERFLOW orERROR_STACK_OVERFLOW StackOverflowException
COR_E_SYNCHRONIZATIONLOCK SynchronizationLockException
COR_E_SYSTEM SystemException
COR_E_TARGET TargetException
COR_E_TARGETINVOCATION TargetInvocationException
COR_E_TARGETPARAMCOUNT TargetParameterCountException
COR_E_THREADINTERRUPTED ThreadInterruptedException
COR_E_THREADSTATE ThreadStateException
COR_E_TYPELOAD TypeLoadException
COR_E_TYPEINITIALIZATION TypeInitializationException
COR_E_VERIFICATION VerificationException

Чтобы получить дополнительные сведения об ошибке, управляемый клиент должен проверить поля созданного объекта исключения. Чтобы объект исключения предоставлял полезную информацию об ошибке, com-объект должен реализовать IErrorInfo интерфейс. Среда выполнения использует сведения, предоставленные IErrorInfo для инициализации объекта исключения.

Если COM-объект не поддерживается IErrorInfo, среда выполнения инициализирует объект исключения со значениями по умолчанию. В следующей таблице перечислены все поля, связанные с объектом исключения, идентифицируют источник сведений по умолчанию при поддержке IErrorInfoCOM-объекта.

Обратите внимание, что среда выполнения в некоторых случаях будет игнорировать значение HRESULT, если в потоке присутствует IErrorInfo. Это возможно в тех случаях, когда HRESULT и IErrorInfo представляют разные ошибки.

Поле Exception Источник сведений из модели COM
ErrorCode Значение HRESULT, возвращенное из вызова.
HelpLink Если IErrorInfo->HelpContext значение ненулевое, строка формируется путем объединения IErrorInfo->GetHelpFile и "#" и IErrorInfo->GetHelpContext. В противном случае строка возвращается из IErrorInfo->GetHelpFile.
InnerException Всегда является пустой ссылкой (Nothing в Visual Basic).
Message Строка, возвращаемая IErrorInfo->GetDescription.
Source Строка, возвращаемая IErrorInfo->GetSource.
StackTrace Трассировка стека.
TargetSite Имя метода, который вернул значение HRESULT со сбоем.

Поля исключений, например MessageSource, и StackTrace недоступны для StackOverflowExceptionних.

См. также