Cómo: Asignar resultados HRESULT y excepciones
Actualización: noviembre 2007
Los métodos COM informan de los errores devolviendo resultados HRESULT, mientras que los métodos .NET lo hacen produciendo excepciones. El motor en tiempo de ejecución controla la transición entre ambos. Cada clase de excepción de .NET Framework se asigna a un resultado HRESULT.
Las clases de excepción definidas por el usuario pueden especificar el resultado HRESULT que sea adecuado. Estas clases de excepción pueden cambiar dinámicamente el resultado HRESULT que se devolverá cuando se genere la excepción estableciendo el campo HResult en el objeto de excepción. El cliente recibe información adicional acerca de la excepción mediante la interfaz IErrorInfo, que se implementa en el objeto .NET en el proceso no administrado.
Si se crea una clase que extiende System.Exception, se debe establecer el campo HRESULT en el momento de la creación. De lo contrario, el valor HRESULT lo asigna la clase base. A un resultado HRESULT existente se le pueden asignar nuevas clases de excepción proporcionando el valor en el constructor de la excepción.
Observe que el motor en tiempo de ejecución a veces omitirá HRESULT en los casos en los que exista IErrorInfo en el subproceso. Este comportamiento se puede producir en los casos en los que HRESULT y IErrorInfo no representen el mismo error.
Crear una nueva clase de excepción y asignarla a un HRESULT
Utilice el código siguiente para crear una nueva clase de excepción llamada NoAccessException y asignarla al HRESULT E_ACCESSDENIED.
Class NoAccessException : public ApplicationException { NoAccessException () { HResult = E_ACCESSDENIED; } } CMyClass::MethodThatThrows { throw new NoAccessException(); }
Puede haber algún programa (en cualquier lenguaje de programación) que use código administrado y no administrado a la vez. Por ejemplo, el contador de referencias personalizado del ejemplo de código siguiente usa el método Marshal.ThrowExceptionForHR(int HResult) para producir una excepción con un valor específico de HRESULT. El método busca el resultado HRESULT y genera el tipo de excepción adecuado. Así, el resultado HRESULT del siguiente fragmento de código genera ArgumentException.
CMyClass::MethodThatThrows
{
Marshal.ThrowExceptionForHR(COR_E_ARGUMENT);
}
En la tabla siguiente se proporcionan todas las asignaciones de cada resultado HRESULT a su clase de excepción correspondiente en .NET Framework.
HRESULT |
Excepción .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 |
Excepción |
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 |
Cualquier otro resultado HRESULT |
COMException |
Para recuperar información de errores extendida, el cliente administrado debe examinar los campos del objeto de excepción generado. Para que el objeto de excepción proporcione información útil acerca del error, el objeto COM debe implementar la interfaz IErrorInfo. El motor de tiempo de ejecución usa la información que proporciona IErrorInfo para inicializar el objeto de excepción.
Si el objeto COM no es compatible con IErrorInfo, el motor de tiempo de ejecución inicializa un objeto de excepción con los valores predeterminados. En la tabla siguiente se enumera cada uno de los campos asociados a un objeto de excepción y se identifica el origen de la información predeterminada cuando el objeto COM es compatible con IErrorInfo.
Observe que el motor en tiempo de ejecución a veces omitirá HRESULT en los casos en los que exista IErrorInfo en el subproceso. Este comportamiento se puede producir en los casos en los que HRESULT y IErrorInfo no representen el mismo error.
Campo de excepción |
Origen de la información de COM |
---|---|
ErrorCode |
Resultado HRESULT devuelto de la llamada. |
HelpLink |
Si IErrorInfo->HelpContext no es cero, la cadena se forma concatenando IErrorInfo->GetHelpFile y "#" y IErrorInfo->GetHelpContext. En caso contrario, la cadena devuelta procede de IErrorInfo->GetHelpFile. |
InnerException |
Es siempre una referencia null (Nothing en Visual Basic). |
Mensaje |
Cadena devuelta de IErrorInfo->GetDescription. |
Origen |
Cadena devuelta de IErrorInfo->GetSource. |
StackTrace |
Seguimiento de la pila. |
TargetSite |
Nombre del método devuelto por el resultado HRESULT con el error. |
Los campos de excepción tales como Message, Source y StackTrace no están disponibles para StackOverflowException.