private static void CheckIfMissingTypeInfoIsExpected(int hresult, bool throwIfMissingExpectedTypeInfo) { Debug.Assert(!ComHresults.IsSuccess(hresult)); // Word.Basic always returns this because of an incorrect implementation of IDispatch.GetTypeInfo // Any implementation that returns E_NOINTERFACE is likely to do so in all environments if (hresult == ComHresults.E_NOINTERFACE) { return; } // This assert is potentially over-restrictive since COM components can behave in quite unexpected ways. // However, asserting the common expected cases ensures that we find out about the unexpected scenarios, and // can investigate the scenarios to ensure that there is no bug in our own code. Debug.Assert(hresult == ComHresults.TYPE_E_LIBNOTREGISTERED); if (throwIfMissingExpectedTypeInfo) { Marshal.ThrowExceptionForHR(hresult); } }
internal static ComTypes.ITypeInfo GetITypeInfoFromIDispatch(IDispatch dispatch, bool throwIfMissingExpectedTypeInfo) { uint typeCount; int hresult = dispatch.TryGetTypeInfoCount(out typeCount); Marshal.ThrowExceptionForHR(hresult); Debug.Assert(typeCount <= 1); if (typeCount == 0) { return(null); } IntPtr typeInfoPtr = IntPtr.Zero; hresult = dispatch.TryGetTypeInfo(0, 0, out typeInfoPtr); if (!ComHresults.IsSuccess(hresult)) { CheckIfMissingTypeInfoIsExpected(hresult, throwIfMissingExpectedTypeInfo); return(null); } if (typeInfoPtr == IntPtr.Zero) // be defensive against components that return IntPtr.Zero { if (throwIfMissingExpectedTypeInfo) { Marshal.ThrowExceptionForHR(ComHresults.E_FAIL); } return(null); } ComTypes.ITypeInfo typeInfo = null; try { typeInfo = Marshal.GetObjectForIUnknown(typeInfoPtr) as ComTypes.ITypeInfo; } finally { Marshal.Release(typeInfoPtr); } return(typeInfo); }
public static void CheckThrowException(int hresult, ref ExcepInfo excepInfo, uint argErr, string message) { if (ComHresults.IsSuccess(hresult)) { return; } switch (hresult) { case ComHresults.DISP_E_BADPARAMCOUNT: // The number of elements provided to DISPPARAMS is different from the number of arguments // accepted by the method or property. throw Error.DispBadParamCount(message); case ComHresults.DISP_E_BADVARTYPE: //One of the arguments in rgvarg is not a valid variant type. break; case ComHresults.DISP_E_EXCEPTION: // The application needs to raise an exception. In this case, the structure passed in pExcepInfo // should be filled in. throw excepInfo.GetException(); case ComHresults.DISP_E_MEMBERNOTFOUND: // The requested member does not exist, or the call to Invoke tried to set the value of a // read-only property. throw Error.DispMemberNotFound(message); case ComHresults.DISP_E_NONAMEDARGS: // This implementation of IDispatch does not support named arguments. throw Error.DispNoNamedArgs(message); case ComHresults.DISP_E_OVERFLOW: // One of the arguments in rgvarg could not be coerced to the specified type. throw Error.DispOverflow(message); case ComHresults.DISP_E_PARAMNOTFOUND: // One of the parameter DISPIDs does not correspond to a parameter on the method. In this case, // puArgErr should be set to the first argument that contains the error. break; case ComHresults.DISP_E_TYPEMISMATCH: // One or more of the arguments could not be coerced. The index within rgvarg of the first // parameter with the incorrect type is returned in the puArgErr parameter. throw Error.DispTypeMismatch(argErr, message); case ComHresults.DISP_E_UNKNOWNINTERFACE: // The interface identifier passed in riid is not IID_NULL. break; case ComHresults.DISP_E_UNKNOWNLCID: // The member being invoked interprets string arguments according to the LCID, and the // LCID is not recognized. break; case ComHresults.DISP_E_PARAMNOTOPTIONAL: // A required parameter was omitted. throw Error.DispParamNotOptional(message); } Marshal.ThrowExceptionForHR(hresult); }