如何:映射 HRESULT 和异常

COM 方法通过返回 HRESULT 来报告错误;.NET 方法则通过引发异常来报告错误。 运行时将处理这两者之间的转换。 .NET Framework 中的每个异常类都会映射到一个 HRESULT。

用户定义的异常类可以指定任何适当的 HRESULT。 当通过设置异常对象的 HResult 字段来生成异常时,这些异常类可以动态地更改所返回的 HRESULT。 有关异常的其他信息通过 IErrorInfo 接口提供给客户端,该接口于非托管进程中在 .NET 对象上实现。

如果创建了扩展 System.Exception 的类,则必须在构造过程中设置 HRESULT 字段。 否则,基类将分配 HRESULT 值。 通过在异常的构造函数中提供 HRESULT 值,可以将新的异常类映射到现有的 HRESULT。

注意,当线程上存在 IErrorInfo 时,运行时有时会忽略 HRESULT。 该行为可能发生在 HRESULT 和 IErrorInfo 不表示相同错误的情况下。

新建异常类并将其映射到 HRESULT

  • 使用以下代码新建一个名为 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 Framework 中的可比异常类的完整关系映射。

HRESULT

.NET 异常

MSEE_E_APPDOMAINUNLOADED

AppDomainUnloadedException

COR_E_APPLICATION

ApplicationException

COR_E_ARGUMENT 或 E_INVALIDARG

ArgumentException

COR_E_ARGUMENTOUTOFRANGE

ArgumentOutOfRangeException

COR_E_ARITHMETIC 或 ERROR_ARITHMETIC_OVERFLOW

ArithmeticException

COR_E_ARRAYTYPEMISMATCH

ArrayTypeMismatchException

COR_E_BADIMAGEFORMAT 或 ERROR_BAD_FORMAT

BadImageFormatException

COR_E_COMEMULATE_ERROR

COMEmulateException

COR_E_CONTEXTMARSHAL

ContextMarshalException

COR_E_CORE

CoreException

NTE_FAIL

CryptographicException

COR_E_DIRECTORYNOTFOUND 或 ERROR_PATH_NOT_FOUND

DirectoryNotFoundException

COR_E_DIVIDEBYZERO

DivideByZeroException

COR_E_DUPLICATEWAITOBJECT

DuplicateWaitObjectException

COR_E_ENDOFSTREAM

EndOfStreamException

COR_E_TYPELOAD

EntryPointNotFoundException

COR_E_EXCEPTION

Exception

COR_E_EXECUTIONENGINE

ExecutionEngineException

COR_E_FIELDACCESS

FieldAccessException

COR_E_FILENOTFOUND 或 ERROR_FILE_NOT_FOUND

FileNotFoundException

COR_E_FORMAT

FormatException

COR_E_INDEXOUTOFRANGE

IndexOutOfRangeException

COR_E_INVALIDCAST 或 E_NOINTERFACE

InvalidCastException

COR_E_INVALIDCOMOBJECT

InvalidComObjectException

COR_E_INVALIDFILTERCRITERIA

InvalidFilterCriteriaException

COR_E_INVALIDOLEVARIANTTYPE

InvalidOleVariantTypeException

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_MULTICASTNOTSUPPORTED

MulticastNotSupportedException

COR_E_NOTFINITENUMBER

NotFiniteNumberException

E_NOTIMPL

NotImplementedException

COR_E_NOTSUPPORTED

NotSupportedException

COR_E_NULLREFERENCE 或 E_POINTER

NullReferenceException

COR_E_OUTOFMEMORY 或

E_OUTOFMEMORY

OutOfMemoryException

COR_E_OVERFLOW

OverflowException

COR_E_PATHTOOLONG 或 ERROR_FILENAME_EXCED_RANGE

PathTooLongException

COR_E_RANK

RankException

COR_E_REFLECTIONTYPELOAD

ReflectionTypeLoadException

COR_E_REMOTING

RemotingException

COR_E_SAFEARRAYTYPEMISMATCH

SafeArrayTypeMismatchException

COR_E_SECURITY

SecurityException

COR_E_SERIALIZATION

SerializationException

COR_E_STACKOVERFLOW 或 ERROR_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_THREADABORTED

ThreadAbortException

COR_E_THREADINTERRUPTED

ThreadInterruptedException

COR_E_THREADSTATE

ThreadStateException

COR_E_THREADSTOP

ThreadStopException

COR_E_TYPELOAD

TypeLoadException

COR_E_TYPEINITIALIZATION

TypeInitializationException

COR_E_VERIFICATION

VerificationException

COR_E_WEAKREFERENCE

WeakReferenceException

COR_E_VTABLECALLSNOTSUPPORTED

VTableCallsNotSupportedException

其他所有 HRESULT

COMException

要检索扩展的错误信息,托管客户端必须检查已生成的异常对象的字段。 要让异常对象提供有关错误的有用信息,COM 对象必须实现 IErrorInfo 接口。 运行时使用 IErrorInfo 所提供的信息来初始化异常对象。

如果 COM 对象不支持 IErrorInfo,运行时将用默认值初始化异常对象。 下表列出了与异常对象相关联的每个字段,并说明了当 COM 对象支持 IErrorInfo 时的默认信息源。

注意,当线程上存在 IErrorInfo 时,运行时有时会忽略 HRESULT。 该行为可能发生在 HRESULT 和 IErrorInfo 不表示相同错误的情况下。

异常字段

COM 信息源

ErrorCode

调用返回的 HRESULT。

HelpLink

如果 IErrorInfo->HelpContext 不为零,字符串将通过串联 IErrorInfo->GetHelpFile 和“#”和 IErrorInfo->GetHelpContext 来形成。 否则,字符串将从 IErrorInfo->GetHelpFile 返回。

InnerException

始终为 null 引用(在 Visual Basic 中为 Nothing)。

消息

IErrorInfo->GetDescription 返回的字符串。

IErrorInfo->GetSource 返回的字符串。

StackTrace

堆栈跟踪。

TargetSite

返回失败 HRESULT 的方法的名称。

MessageSourceStackTrace 等异常字段不可用于 StackOverflowException

请参见

概念

处理和引发异常

其他资源

高级 COM 互操作性