作法:對應 HRESULT 和例外狀況

COM 方法是藉由傳回 HRESULT 來報告錯誤;.NET 方法則是藉由擲回例外狀況來報告錯誤。 執行階段則負責處理兩者之間的轉換。 .NET Framework 的每一個例外狀況類別都會對應到一個 HRESULT。

使用者定義的例外狀況類別可以指定任何適當的 HRESULT。 這些例外狀況類別可以在例外狀況物件上設定 HResult 欄位時,動態變更要傳回的 HRESULT。 例外狀況的其他資訊是透過 IErrorInfo 介面提供給用戶端,該介面是在非受控進程的 .net 物件上所執行。

如果您建立擴充 System.Exception 的類別,則必須在結構期間設定 HRESULT 欄位。 否則,基底類別會指派 HRESULT 值。 您可以在例外狀況的建構函式中提供值,將新的例外狀況類別對應到現有的 HRESULT。

請注意,執行階段有時候會忽略 HRESULT,以應付萬一執行緒上存在 IErrorInfo 的情況。 如果 HRESULTIErrorInfo 並不代表相同的錯誤,就可能會發生這種行為。

建立新的例外狀況類別並將其對應到 HRESULT

  1. 使用下列程式碼來建立稱為 NoAccessException 的新例外狀況類別,並將其對應到 HRESULT E_ACCESSDENIED

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

您也許會遇到同時使用 Managed 和 Unmanaged 程式碼的程式 (以任何程式語言所撰寫)。 例如,在下列程式碼範例中,自訂的封送處理器會使用 Marshal.ThrowExceptionForHR(int HResult) 方法來擲回具有特定 HRESULT 值的例外狀況。 此方法會查詢 HRESULT 並產生適當的例外狀況,類型。 例如,下列程式碼片段中的 HRESULT 會產生 ArgumentException

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

下表提供從 HRESULT 到其在 .NET 中可比較之例外狀況類別的一般對應。 不含明確對應的 HRESULT 值會對應至 COMException 。 完成最新的對應可以在 dotnet/runtime 儲存機制中找到。

HRESULT .NET 例外狀況
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENTE_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

若要擷取擴充錯誤資訊,Managed 用戶端必須檢查所產生之例外狀況物件的欄位。 若要讓例外狀況物件提供有關錯誤的實用資訊,COM 物件必須執行 IErrorInfo 介面。 執行時間會使用提供 IErrorInfo 的資訊來初始化例外狀況物件。

如果 COM 物件不支援 IErrorInfo ,則執行時間會使用預設值來初始化例外狀況物件。 下表列出與例外狀況物件相關聯的每個欄位,並在 COM 物件支援 IErrorInfo 時,識別預設資訊的來源。

請注意,執行階段有時候會忽略 HRESULT,以應付萬一執行緒上存在 IErrorInfo 的情況。 如果 HRESULTIErrorInfo 並不代表相同的錯誤,就可能會發生這種行為。

例外狀況欄位 來自 COM 的資訊來源
ErrorCode 從呼叫傳回的 HRESULT。
HelpLink 如果 IErrorInfo->HelpContext 是非零值,則字串會藉由串連 IErrorInfo->GetHelpFile 和 "#" 和 IErrorInfo->GetHelpContext 來形成。 否則會從 IErrorInfo->GetHelpFile 傳回字串。
InnerException 在 Visual Basic) 中,一律為 null 參考 (Nothing
Message 從傳回的 IErrorInfo->GetDescription 字串。
Source 從傳回的 IErrorInfo->GetSource 字串。
StackTrace 堆疊追蹤。
TargetSite 傳回失敗 HRESULT 之方法的名稱。

例外狀況欄位(例如 MessageSourceStackTrace )無法供使用 StackOverflowException

另請參閱