如何:映射 HRESULT 和异常

更新:2007 年 11 月

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)。

Message

IErrorInfo->GetDescription 返回的字符串。

Source

IErrorInfo->GetSource 返回的字符串。

StackTrace

堆栈跟踪。

TargetSite

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

MessageSourceStackTrace 等异常字段不可用于 StackOverflowException

请参见

其他资源

高级 COM 互操作性

处理和引发异常