作法:對應 HRESULT 和例外狀況How to: Map HRESULTs and Exceptions

COM 方法是藉由傳回 HRESULT 來報告錯誤;.NET 方法則是藉由擲回例外狀況來報告錯誤。COM methods report errors by returning HRESULTs; .NET methods report them by throwing exceptions. 執行階段則負責處理兩者之間的轉換。The runtime handles the transition between the two. .NET Framework 的每一個例外狀況類別都會對應到一個 HRESULT。Each exception class in the .NET Framework maps to an HRESULT.

使用者定義的例外狀況類別可以指定任何適當的 HRESULT。User-defined exception classes can specify whatever HRESULT is appropriate. 當例外狀況是藉由設定例外狀況物件上的 HResult 欄位而產生時,這些例外狀況類別可以動態地變更要傳回的 HRESULT。These exception classes can dynamically change the HRESULT to be returned when the exception is generated by setting the HResult field on the exception object. 例外狀況的其他資訊會透過 IErrorInfo 介面提供給用戶端,而該介面是實作於 Unmanaged 處理序中的 .NET 物件上。Additional information about the exception is provided to the client through the IErrorInfo interface, which is implemented on the .NET object in the unmanaged process.

如果您建立了擴充 System.Exception 的類別,則必須在建構期間設定 HRESULT 欄位。If you create a class that extends System.Exception, you must set the HRESULT field during construction. 否則,基底類別會指派 HRESULT 值。Otherwise, the base class assigns the HRESULT value. 您可以在例外狀況的建構函式中提供值,將新的例外狀況類別對應到現有的 HRESULT。You can map new exception classes to an existing HRESULT by supplying the value in the exception's constructor.

請注意,執行階段有時候會忽略 HRESULT,以應付萬一執行緒上存在 IErrorInfo 的情況。Note that the runtime will sometimes ignore an HRESULT in cases where there is an IErrorInfo present on the thread. 如果 HRESULTIErrorInfo 並不代表相同的錯誤,就可能會發生這種行為。This behavior can occur in cases where the HRESULT and the IErrorInfo do not represent the same error.

建立新的例外狀況類別並將其對應到 HRESULTTo create a new exception class and map it to an HRESULT

  1. 使用下列程式碼來建立稱為 NoAccessException 的新例外狀況類別,並將其對應到 HRESULT E_ACCESSDENIEDUse the following code to create a new exception class called NoAccessException and map it to the HRESULT E_ACCESSDENIED.

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

您也許會遇到同時使用 Managed 和 Unmanaged 程式碼的程式 (以任何程式語言所撰寫)。You might encounter a program (in any programming language) that uses both managed and unmanaged code at the same time. 例如,下列程式碼範例中的自訂封送處理器是使用 Marshal.ThrowExceptionForHR(int HResult) 方法來擲回具有特定 HRESULT 值的例外狀況。For example, the custom marshaler in the following code example uses the Marshal.ThrowExceptionForHR(int HResult) method to throw an exception with a specific HRESULT value. 此方法會查詢 HRESULT 並產生適當的例外狀況,類型。The method looks up the HRESULT and generates the appropriate exception type. 例如,下列程式碼片段中的 HRESULT 會產生 ArgumentExceptionFor example, the HRESULT in the following code fragment generates ArgumentException.

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

下表提供每一個 HRESULT 與其在 .NET Framework 中可比較之例外狀況類別的完整對應。The following table provides the complete mapping from each HRESULT to its comparable exception class in the .NET Framework.

HRESULTHRESULT .NET 例外狀況.NET exception
MSEE_E_APPDOMAINUNLOADEDMSEE_E_APPDOMAINUNLOADED AppDomainUnloadedExceptionAppDomainUnloadedException
COR_E_APPLICATIONCOR_E_APPLICATION ApplicationExceptionApplicationException
COR_E_ARGUMENT 或 E_INVALIDARGCOR_E_ARGUMENT or E_INVALIDARG ArgumentExceptionArgumentException
COR_E_ARGUMENTOUTOFRANGECOR_E_ARGUMENTOUTOFRANGE ArgumentOutOfRangeExceptionArgumentOutOfRangeException
COR_E_ARITHMETIC 或 ERROR_ARITHMETIC_OVERFLOWCOR_E_ARITHMETIC or ERROR_ARITHMETIC_OVERFLOW ArithmeticExceptionArithmeticException
COR_E_ARRAYTYPEMISMATCHCOR_E_ARRAYTYPEMISMATCH ArrayTypeMismatchExceptionArrayTypeMismatchException
COR_E_BADIMAGEFORMAT 或 ERROR_BAD_FORMATCOR_E_BADIMAGEFORMAT or ERROR_BAD_FORMAT BadImageFormatExceptionBadImageFormatException
COR_E_COMEMULATE_ERRORCOR_E_COMEMULATE_ERROR COMEmulateExceptionCOMEmulateException
COR_E_CONTEXTMARSHALCOR_E_CONTEXTMARSHAL ContextMarshalExceptionContextMarshalException
COR_E_CORECOR_E_CORE CoreExceptionCoreException
NTE_FAILNTE_FAIL CryptographicExceptionCryptographicException
COR_E_DIRECTORYNOTFOUND 或 ERROR_PATH_NOT_FOUNDCOR_E_DIRECTORYNOTFOUND or ERROR_PATH_NOT_FOUND DirectoryNotFoundExceptionDirectoryNotFoundException
COR_E_DIVIDEBYZEROCOR_E_DIVIDEBYZERO DivideByZeroExceptionDivideByZeroException
COR_E_DUPLICATEWAITOBJECTCOR_E_DUPLICATEWAITOBJECT DuplicateWaitObjectExceptionDuplicateWaitObjectException
COR_E_ENDOFSTREAMCOR_E_ENDOFSTREAM EndOfStreamExceptionEndOfStreamException
COR_E_TYPELOADCOR_E_TYPELOAD EntryPointNotFoundExceptionEntryPointNotFoundException
COR_E_EXCEPTIONCOR_E_EXCEPTION 例外Exception
COR_E_EXECUTIONENGINECOR_E_EXECUTIONENGINE ExecutionEngineExceptionExecutionEngineException
COR_E_FIELDACCESSCOR_E_FIELDACCESS FieldAccessExceptionFieldAccessException
COR_E_FILENOTFOUND 或 ERROR_FILE_NOT_FOUNDCOR_E_FILENOTFOUND or ERROR_FILE_NOT_FOUND FileNotFoundExceptionFileNotFoundException
COR_E_FORMATCOR_E_FORMAT FormatExceptionFormatException
COR_E_INDEXOUTOFRANGECOR_E_INDEXOUTOFRANGE IndexOutOfRangeExceptionIndexOutOfRangeException
COR_E_INVALIDCAST 或 E_NOINTERFACECOR_E_INVALIDCAST or E_NOINTERFACE InvalidCastExceptionInvalidCastException
COR_E_INVALIDCOMOBJECTCOR_E_INVALIDCOMOBJECT InvalidComObjectExceptionInvalidComObjectException
COR_E_INVALIDFILTERCRITERIACOR_E_INVALIDFILTERCRITERIA InvalidFilterCriteriaExceptionInvalidFilterCriteriaException
COR_E_INVALIDOLEVARIANTTYPECOR_E_INVALIDOLEVARIANTTYPE InvalidOleVariantTypeExceptionInvalidOleVariantTypeException
COR_E_INVALIDOPERATIONCOR_E_INVALIDOPERATION InvalidOperationExceptionInvalidOperationException
COR_E_IOCOR_E_IO IOExceptionIOException
COR_E_MEMBERACCESSCOR_E_MEMBERACCESS AccessExceptionAccessException
COR_E_METHODACCESSCOR_E_METHODACCESS MethodAccessExceptionMethodAccessException
COR_E_MISSINGFIELDCOR_E_MISSINGFIELD MissingFieldExceptionMissingFieldException
COR_E_MISSINGMANIFESTRESOURCECOR_E_MISSINGMANIFESTRESOURCE MissingManifestResourceExceptionMissingManifestResourceException
COR_E_MISSINGMEMBERCOR_E_MISSINGMEMBER MissingMemberExceptionMissingMemberException
COR_E_MISSINGMETHODCOR_E_MISSINGMETHOD MissingMethodExceptionMissingMethodException
COR_E_MULTICASTNOTSUPPORTEDCOR_E_MULTICASTNOTSUPPORTED MulticastNotSupportedExceptionMulticastNotSupportedException
COR_E_NOTFINITENUMBERCOR_E_NOTFINITENUMBER NotFiniteNumberExceptionNotFiniteNumberException
E_NOTIMPLE_NOTIMPL NotImplementedExceptionNotImplementedException
COR_E_NOTSUPPORTEDCOR_E_NOTSUPPORTED NotSupportedExceptionNotSupportedException
COR_E_NULLREFERENCE 或 E_POINTERCOR_E_NULLREFERENCE orE_POINTER NullReferenceExceptionNullReferenceException
COR_E_OUTOFMEMORY 或COR_E_OUTOFMEMORY or

E_OUTOFMEMORYE_OUTOFMEMORY
OutOfMemoryExceptionOutOfMemoryException
COR_E_OVERFLOWCOR_E_OVERFLOW OverflowExceptionOverflowException
COR_E_PATHTOOLONG 或 ERROR_FILENAME_EXCED_RANGECOR_E_PATHTOOLONG or ERROR_FILENAME_EXCED_RANGE PathTooLongExceptionPathTooLongException
COR_E_RANKCOR_E_RANK RankExceptionRankException
COR_E_REFLECTIONTYPELOADCOR_E_REFLECTIONTYPELOAD ReflectionTypeLoadExceptionReflectionTypeLoadException
COR_E_REMOTINGCOR_E_REMOTING RemotingExceptionRemotingException
COR_E_SAFEARRAYTYPEMISMATCHCOR_E_SAFEARRAYTYPEMISMATCH SafeArrayTypeMismatchExceptionSafeArrayTypeMismatchException
COR_E_SECURITYCOR_E_SECURITY SecurityExceptionSecurityException
COR_E_SERIALIZATIONCOR_E_SERIALIZATION SerializationExceptionSerializationException
COR_E_STACKOVERFLOW 或 ERROR_STACK_OVERFLOWCOR_E_STACKOVERFLOW orERROR_STACK_OVERFLOW StackOverflowExceptionStackOverflowException
COR_E_SYNCHRONIZATIONLOCKCOR_E_SYNCHRONIZATIONLOCK SynchronizationLockExceptionSynchronizationLockException
COR_E_SYSTEMCOR_E_SYSTEM SystemExceptionSystemException
COR_E_TARGETCOR_E_TARGET TargetExceptionTargetException
COR_E_TARGETINVOCATIONCOR_E_TARGETINVOCATION TargetInvocationExceptionTargetInvocationException
COR_E_TARGETPARAMCOUNTCOR_E_TARGETPARAMCOUNT TargetParameterCountExceptionTargetParameterCountException
COR_E_THREADABORTEDCOR_E_THREADABORTED ThreadAbortExceptionThreadAbortException
COR_E_THREADINTERRUPTEDCOR_E_THREADINTERRUPTED ThreadInterruptedExceptionThreadInterruptedException
COR_E_THREADSTATECOR_E_THREADSTATE ThreadStateExceptionThreadStateException
COR_E_THREADSTOPCOR_E_THREADSTOP ThreadStopExceptionThreadStopException
COR_E_TYPELOADCOR_E_TYPELOAD TypeLoadExceptionTypeLoadException
COR_E_TYPEINITIALIZATIONCOR_E_TYPEINITIALIZATION TypeInitializationExceptionTypeInitializationException
COR_E_VERIFICATIONCOR_E_VERIFICATION VerificationExceptionVerificationException
COR_E_WEAKREFERENCECOR_E_WEAKREFERENCE WeakReferenceExceptionWeakReferenceException
COR_E_VTABLECALLSNOTSUPPORTEDCOR_E_VTABLECALLSNOTSUPPORTED VTableCallsNotSupportedExceptionVTableCallsNotSupportedException
所有其他的 HRESULTAll other HRESULTs COMExceptionCOMException

若要擷取擴充錯誤資訊,Managed 用戶端必須檢查所產生之例外狀況物件的欄位。To retrieve extended error information, the managed client must examine the fields of the exception object that was generated. 若要讓例外狀況物件提供有關錯誤的有用資訊,COM 物件必須實作 IErrorInfo 介面。For the exception object to provide useful information about an error, the COM object must implement the IErrorInfo interface. 執行階段會使用 IErrorInfo 提供的資訊來初始化例外狀況物件。The runtime uses the information provided by IErrorInfo to initialize the exception object.

如果 COM 物件不支援 IErrorInfo,執行階段會使用預設值來初始化例外狀況物件。If the COM object does not support IErrorInfo, the runtime initializes an exception object with default values. 下表列出與例外狀況物件建立關聯的每一個欄位,並且指出當 COM 物件支援 IErrorInfo 時的預設資訊來源。The following table lists each field associated with an exception object and identifies the source of default information when the COM object supports IErrorInfo.

請注意,執行階段有時候會忽略 HRESULT,以應付萬一執行緒上存在 IErrorInfo 的情況。Note that the runtime will sometimes ignore an HRESULT in cases where there is an IErrorInfo present on the thread. 如果 HRESULTIErrorInfo 並不代表相同的錯誤,就可能會發生這種行為。This behavior can occur in cases where the HRESULT and the IErrorInfo do not represent the same error.

例外狀況欄位Exception field 來自 COM 的資訊來源Source of Information from COM
ErrorCodeErrorCode 從呼叫傳回的 HRESULT。HRESULT returned from call.
HelpLinkHelpLink 如果 IErrorInfo->HelpContext 是非零值,則字串是由串連 IErrorInfo->GetHelpFile、"#" 和 IErrorInfo->GetHelpContext 所構成。If IErrorInfo->HelpContext is nonzero, the string is formed by concatenating IErrorInfo->GetHelpFile and "#" and IErrorInfo->GetHelpContext. 否則,字串是從 IErrorInfo->GetHelpFile 所傳回。Otherwise the string is returned from IErrorInfo->GetHelpFile.
InnerExceptionInnerException 一律為 Null 參考 (在 Visual Basic 中為 Nothing)。Always a null reference (Nothing in Visual Basic).
訊息Message IErrorInfo->GetDescription 傳回的字串。String returned from IErrorInfo->GetDescription.
原始程式檔Source IErrorInfo->GetSource 傳回的字串。String returned from IErrorInfo->GetSource.
StackTraceStackTrace 堆疊追蹤。The stack trace.
TargetSiteTargetSite 傳回失敗 HRESULT 之方法的名稱。The name of the method that returned the failing HRESULT.

MessageSourceStackTrace 之類的例外狀況欄位,並不適用於 StackOverflowExceptionException fields, such as Message, Source, and StackTrace are not available for the StackOverflowException.

另請參閱See also