Porady: mapowanie wyników HRESULT i wyjątków

Metody MODELU COM zgłaszają błędy, zwracając wartości HRESULTs; metody platformy .NET zgłaszają je, zgłaszając wyjątki. Środowisko uruchomieniowe obsługuje przejście między nimi. Każda klasa wyjątków w programie .NET Framework mapuje na hrESULT.

Klasy wyjątków zdefiniowane przez użytkownika mogą określać, co hrESULT jest odpowiednie. Te klasy wyjątków mogą dynamicznie zmieniać wartość HRESULT, która ma być zwracana po wygenerowaniu wyjątku, ustawiając HResult pole w obiekcie wyjątku. Dodatkowe informacje o wyjątku są udostępniane klientowi za pośrednictwem interfejsu IErrorInfo , który jest implementowany w obiekcie .NET w procesie niezarządzanych.

Jeśli tworzysz klasę, która rozszerza System.Exceptionklasę , należy ustawić pole HRESULT podczas budowy. W przeciwnym razie klasa bazowa przypisuje wartość HRESULT. Nowe klasy wyjątków można mapować na istniejącą wartość HRESULT, podając wartość w konstruktorze wyjątku.

Należy pamiętać, że środowisko uruchomieniowe czasami ignoruje HRESULT element w przypadkach, w których wątek występuje IErrorInfo . To zachowanie może wystąpić w przypadkach, gdy element HRESULT i IErrorInfo nie reprezentuje tego samego błędu.

Aby utworzyć nową klasę wyjątków i zamapować ją na HRESULT

  1. Użyj następującego kodu, aby utworzyć nową klasę wyjątków o nazwie NoAccessException i zamapować ją na HRESULT E_ACCESSDENIED.

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

Może wystąpić program (w dowolnym języku programowania), który używa jednocześnie kodu zarządzanego i niezarządzanego. Na przykład niestandardowy marshaller w poniższym przykładzie kodu używa Marshal.ThrowExceptionForHR(int HResult) metody , aby zgłosić wyjątek z określoną wartością HRESULT. Metoda wyszukuje HRESULT i generuje odpowiedni typ wyjątku. Na przykład hrESULT w poniższym fragmentze kodu generuje ArgumentExceptionwartość .

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

Poniższa tabela zawiera typowe mapowania z HRESULT na porównywalną klasę wyjątków na platformie .NET. Wartości HRESULT bez jawnych mapowań są mapowane na COMException. Kompletne mapowanie aktualne można znaleźć w repozytorium dotnet/runtime.

HRESULT Wyjątek platformy .NET
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENT lub 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

Aby pobrać rozszerzone informacje o błędzie, zarządzany klient musi zbadać pola wygenerowanego obiektu wyjątku. Aby obiekt wyjątku dostarczał przydatne informacje o błędzie, obiekt COM musi zaimplementować IErrorInfo interfejs. Środowisko uruchomieniowe używa informacji dostarczonych przez IErrorInfo program do zainicjowania obiektu wyjątku.

Jeśli obiekt COM nie obsługuje IErrorInfo, środowisko uruchomieniowe inicjuje obiekt wyjątku z wartościami domyślnymi. W poniższej tabeli wymieniono każde pole skojarzone z obiektem wyjątku i identyfikuje źródło informacji domyślnych, gdy obiekt COM obsługuje IErrorInfofunkcję .

Należy pamiętać, że środowisko uruchomieniowe czasami ignoruje HRESULT element w przypadkach, w których wątek występuje IErrorInfo . To zachowanie może wystąpić w przypadkach, gdy element HRESULT i IErrorInfo nie reprezentuje tego samego błędu.

Pole wyjątku Źródło informacji z modelu COM
ErrorCode HRESULT zwrócony z wywołania.
HelpLink Jeśli IErrorInfo->HelpContext jest nonzero, ciąg jest tworzony przez łączenie IErrorInfo->GetHelpFile i "#" i IErrorInfo->GetHelpContext. W przeciwnym razie ciąg jest zwracany z IErrorInfo->GetHelpFile.
InnerException Zawsze odwołanie o wartości null (Nothing w Visual Basic).
Message Ciąg zwrócony z IErrorInfo->GetDescription.
Source Ciąg zwrócony z IErrorInfo->GetSource.
StackTrace Ślad stosu.
TargetSite Nazwa metody, która zwróciła błąd HRESULT.

Pola wyjątków, takie jak Message, Sourcei StackTrace nie są dostępne dla elementu StackOverflowException.

Zobacz też