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.

Vea también

Otros recursos

Interoperabilidad COM avanzada

Controlar y generar excepciones