Procedura: Eseguire il mapping di HRESULT ed eccezioni

I metodi COM segnalano gli errori restituendo HRESULT; .NET metodi li segnalano generando eccezioni. Il runtime gestisce la transizione tra i due. Ogni classe di eccezione in .NET esegue il mapping a un HRESULT.

Le classi di eccezioni definite dall'utente possono specificare qualsiasi HRESULT appropriato. Queste classi di eccezioni possono modificare dinamicamente il valore HRESULT in modo che venga restituito quando l'eccezione viene generata impostando il HResult campo sull'oggetto eccezione. Informazioni aggiuntive sull'eccezione vengono fornite al client tramite l'interfaccia IErrorInfo , implementata nell'oggetto .NET nel processo non gestito.

Se si crea una classe che estende System.Exception, è necessario impostare il campo HRESULT durante la costruzione. In caso contrario, la classe base assegna il valore HRESULT. È possibile eseguire il mapping di nuove classi di eccezioni a un HRESULT esistente specificando il valore nel costruttore dell'eccezione.

Si noti che il runtime a volte ignora un HRESULT nei casi in cui è presente un IErrorInfo sul thread. Questo comportamento può verificarsi nei casi in cui HRESULT e non IErrorInfo rappresentano lo stesso errore.

Per creare una nuova classe di eccezione ed eseguirne il mapping a un HRESULT

  1. Usare il codice seguente per creare una nuova classe di eccezione denominata NoAccessException ed eseguirne il mapping a HRESULT E_ACCESSDENIED.

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

È possibile che si verifichi un programma (in qualsiasi linguaggio di programmazione) che usa codice gestito e non gestito contemporaneamente. Ad esempio, il marshaller personalizzato nell'esempio di codice seguente usa il Marshal.ThrowExceptionForHR(int HResult) metodo per generare un'eccezione con un valore HRESULT specifico. Il metodo cerca HRESULT e genera il tipo di eccezione appropriato. Ad esempio, HRESULT nel frammento di codice seguente genera ArgumentException.

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

La tabella seguente fornisce i mapping comuni di HRESULT alla relativa classe di eccezione paragonabile in .NET. I valori HRESULT senza mapping espliciti vengono mappati a COMException. La mappatura completa e aggiornata è disponibile nel repository dotnet/runtime.

HRESULT eccezione .NET
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENT oppure 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

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

Se l'oggetto COM non supporta IErrorInfo, il runtime inizializza un oggetto eccezione con valori predefiniti. La tabella seguente elenca ogni campo associato a un oggetto eccezione e identifica l'origine delle informazioni predefinite quando l'oggetto COM supporta IErrorInfo.

Si noti che il runtime a volte ignorerà un HRESULT nei casi in cui è presente un IErrorInfo sul thread. Questo comportamento può verificarsi nei casi in cui HRESULT e non IErrorInfo rappresentano lo stesso errore.

Campo dell’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 Nome del metodo che ha restituito l'errore HRESULT.

I campi eccezione, ad esempio Message, Sourcee StackTrace non sono disponibili per .StackOverflowException

Vedere anche