Procedura: eseguire il mapping di HRESULT ed eccezioni

Aggiornamento: novembre 2007

Per segnalare il verificarsi di un errore, i metodi COM restituiscono un HRESULT. I metodi .NET, invece, generano un'eccezione. Il runtime gestisce la transizione tra i due. Ogni classe che identifica un'eccezione in .NET Framework è associata a un HRESULT.

Le classi di eccezione definite dall'utente possono specificare un HRESULT appropriato. Impostando il campo HResult dell'oggetto di eccezione, tali classi di eccezione possono modificare dinamicamente l'HRESULT che deve essere restituito quando viene generata l'eccezione. Informazioni aggiuntive sull'eccezione vengono fornite al client tramite l'interfaccia IErrorInfo, che è implementata dall'oggetto .NET nel processo non gestito.

Se si crea una classe che estende System.Exception, sarà necessario impostare il campo HRESULT durante la costruzione. In caso contrario, sarà la classe base a assegnare il valore di HRESULT. È possibile associare nuove classi di eccezione a un HRESULT esistente fornendo il valore nel costruttore dell'eccezione.

Si noti che talvolta un HRESULT può essere ignorato dal runtime quando è presente un'interfaccia IErrorInfo sul thread. Questo comportamento può verificarsi nei casi in cui l'HRESULT e l'interfaccia IErrorInfo non rappresentano lo stesso errore.

Per creare una nuova classe di eccezione e mapparla a un HRESULT

  • Utilizzare il codice seguente per creare una nuova classe di eccezione denominata NoAccessException e mapparla al HRESULT E_ACCESSDENIED.

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

È possibile imbattersi in un programma (in qualsiasi linguaggio di programmazione) che utilizza contemporaneamente codice gestito e codice non gestito. Il gestore di marshalling personalizzato illustrato nel codice che segue utilizza ad esempio il metodo Marshal.ThrowExceptionForHR(int HResult) per generare un'eccezione con uno specifico valore di HRESULT. Il metodo esamina l'HRESULT e genera il tipo di eccezione appropriato. L'HRESULT del frammento di codice riportato di seguito genera ad esempio ArgumentException.

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

Nella tabella che segue viene fornita la mappa completa delle associazioni tra ciascun HRESULT e la classe di eccezione di .NET Framework ad esso paragonabile.

HRESULT

Eccezione .NET

MSEE_E_APPDOMAINUNLOADED

AppDomainUnloadedException

COR_E_APPLICATION

ApplicationException

COR_E_ARGUMENT o E_INVALIDARG

ArgumentException

COR_E_ARGUMENTOUTOFRANGE

ArgumentOutOfRangeException

COR_E_ARITHMETIC o ERROR_ARITHMETIC_OVERFLOW

ArithmeticException

COR_E_ARRAYTYPEMISMATCH

ArrayTypeMismatchException

COR_E_BADIMAGEFORMAT o ERROR_BAD_FORMAT

BadImageFormatException

COR_E_COMEMULATE_ERROR

COMEmulateException

COR_E_CONTEXTMARSHAL

ContextMarshalException

COR_E_CORE

CoreException

NTE_FAIL

CryptographicException

COR_E_DIRECTORYNOTFOUND o ERROR_PATH_NOT_FOUND

DirectoryNotFoundException

COR_E_DIVIDEBYZERO

DivideByZeroException

COR_E_DUPLICATEWAITOBJECT

DuplicateWaitObjectException

COR_E_ENDOFSTREAM

EndOfStreamException

COR_E_TYPELOAD

EntryPointNotFoundException

COR_E_EXCEPTION

Eccezione

COR_E_EXECUTIONENGINE

ExecutionEngineException

COR_E_FIELDACCESS

FieldAccessException

COR_E_FILENOTFOUND o ERROR_FILE_NOT_FOUND

FileNotFoundException

COR_E_FORMAT

FormatException

COR_E_INDEXOUTOFRANGE

IndexOutOfRangeException

COR_E_INVALIDCAST o 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 o E_POINTER

NullReferenceException

COR_E_OUTOFMEMORY o

E_OUTOFMEMORY

OutOfMemoryException

COR_E_OVERFLOW

OverflowException

COR_E_PATHTOOLONG o 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 o 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

Tutti gli altri HRESULT

COMException

Per recuperare informazioni sull'errore, il client gestito deve esaminare i campi dell'oggetto di eccezione generato. Affinché l'oggetto di eccezione fornisca informazioni utili su un errore, è necessario che l'oggetto COM implementi l'interfaccia IErrorInfo. Il runtime utilizza le informazioni fornite da IErrorInfo per inizializzare l'oggetto di eccezione.

Se l'oggetto COM non supporta IErrorInfo, il runtime inizializzerà un oggetto di eccezione con i valori predefiniti. Nella tabella che segue vengono elencati tutti i campi associati a un oggetto di eccezione e viene identificata l'origine delle informazioni predefinite adottata quando l'oggetto COM supporta IErrorInfo.

Si noti che talvolta un HRESULT può essere ignorato dal runtime quando è presente un'interfaccia IErrorInfo sul thread. Questo comportamento può verificarsi nei casi in cui l'HRESULT e l'interfaccia IErrorInfo non rappresentano lo stesso errore.

Campo di eccezione

Origine delle informazioni da COM

ErrorCode

HRESULT restituito dalla chiamata.

HelpLink

Se IErrorInfo->HelpContext è diverso da zero, la stringa viene formata concatenando IErrorInfo->GetHelpFile e "#" e IErrorInfo->GetHelpContext. In caso contrario, la stringa viene restituita da IErrorInfo->GetHelpFile.

InnerException

Sempre un riferimento Null (Nothing in Visual Basic).

Message

Stringa restituita da IErrorInfo->GetDescription.

Source

Stringa restituita da IErrorInfo->GetSource.

StackTrace

La traccia dello stack.

TargetSite

Il nome del metodo che ha restituito l'HRESULT di errore.

I campi di eccezione, quali Message, Source e StackTrace, non sono disponibili per StackOverflowException.

Vedere anche

Altre risorse

Interoperabilità COM avanzata

Gestione e generazione di eccezioni