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.