方法: HRESULT と例外をマップする

COM メソッドは、HRESULT を返すことによってエラーを報告します。.NETメソッドは、例外をスローすることによってそれらを報告します。 ランタイムは、2 つの間の遷移を処理します。 .NET内の各例外クラスは HRESULT にマップされます。

ユーザー定義の例外クラスは、適切な HRESULT を指定できます。 これらの例外クラスは、例外オブジェクトに HResult フィールドを設定することによって、例外が生成されたときに返される HRESULT を動的に変更できます。 例外に関する追加情報は、アンマネージ プロセスの.NET オブジェクトに実装されるIErrorInfo インターフェイスを介してクライアントに提供されます。

System.Exception拡張するクラスを作成する場合は、構築時に HRESULT フィールドを設定する必要があります。 それ以外の場合、基本クラスは HRESULT 値を割り当てます。 新しい例外クラスを既存の HRESULT にマップするには、例外のコンストラクターで値を指定します。

スレッドにHRESULTが存在する場合、ランタイムはIErrorInfoを無視することがあります。 この動作は、 HRESULTIErrorInfo が同じエラーを表していない場合に発生する可能性があります。

新しい例外クラスを作成して HRESULT にマップするには

  1. 次のコードを使用して、 NoAccessException という新しい例外クラスを作成し、HRESULT E_ACCESSDENIEDにマップします。

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

マネージド コードとアンマネージド コードの両方を同時に使用するプログラム (任意のプログラミング言語) が発生する場合があります。 たとえば、次のコード例のカスタム マーシャラーは、 Marshal.ThrowExceptionForHR(int HResult) メソッドを使用して、特定の HRESULT 値を持つ例外をスローします。 メソッドは HRESULT を検索し、適切な例外の種類を生成します。 たとえば、次のコード フラグメントの HRESULT は ArgumentExceptionを生成します。

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

次の表に、HRESULT から、.NETの同等の例外クラスへの一般的なマッピングを示します。 明示的なマッピングのない HRESULT 値は、 COMExceptionにマップされます。 完全な最新のマッピングは、dotnet/runtime リポジトリで確認できます。

HRESULT .NET例外
COR_E_APPLICATION ApplicationException
COR_E_ARGUMENT または 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

拡張エラー情報を取得するには、マネージド クライアントが生成された例外オブジェクトのフィールドを調べる必要があります。 例外オブジェクトがエラーに関する有用な情報を提供するには、COM オブジェクトで IErrorInfo インターフェイスを実装する必要があります。 ランタイムは、 IErrorInfo によって提供される情報を使用して例外オブジェクトを初期化します。

COM オブジェクトが IErrorInfoをサポートしていない場合、ランタイムは既定値を使用して例外オブジェクトを初期化します。 次の表に、例外オブジェクトに関連付けられている各フィールドを示し、COM オブジェクトが IErrorInfoをサポートする場合の既定の情報のソースを示します。

スレッドにHRESULTが存在する場合、ランタイムはIErrorInfoを無視することがあります。 この動作は、 HRESULTIErrorInfo が同じエラーを表していない場合に発生する可能性があります。

例外フィールド COM からの情報ソース
ErrorCode 呼び出しから返された HRESULT。
HelpLink IErrorInfo->HelpContextが 0 以外の場合、文字列はIErrorInfo->GetHelpFileと "#" とIErrorInfo->GetHelpContextを連結して形成されます。 それ以外の場合、文字列は IErrorInfo->GetHelpFileから返されます。
InnerException 常に null 参照です (Visual Basic では Nothing)。
Message IErrorInfo->GetDescriptionから返される文字列。
Source IErrorInfo->GetSourceから返される文字列。
StackTrace スタック トレース。
TargetSite 失敗した HRESULT を返したメソッドの名前。

MessageSourceStackTraceなどの例外フィールドは、StackOverflowExceptionでは使用できません。

こちらも参照ください