public static Type GetTypeOrTypeInfo(this object value) { var type = value.GetType(); IDispatch dispatch = null; Type typeInfo = null; TYPEKIND typeInfoKind = 0; TYPEFLAGS typeInfoFlags = 0; if (type.IsUnknownCOMObject()) { // This appears to be a generic COM object with no specific type information. // Attempt to acquire COM type information via IDispatch or IProvideClassInfo. dispatch = value as IDispatch; if (dispatch != null) { uint count; if (RawCOMHelpers.HResult.Succeeded(dispatch.GetTypeInfoCount(out count)) && (count > 0)) { ITypeInfo tempTypeInfo; if (RawCOMHelpers.HResult.Succeeded(dispatch.GetTypeInfo(0, 0, out tempTypeInfo))) { typeInfo = GetTypeForTypeInfo(tempTypeInfo); typeInfoKind = GetTypeInfoKind(tempTypeInfo); typeInfoFlags = GetTypeInfoFlags(tempTypeInfo); } } } if (typeInfo == null) { var provideClassInfo = value as IProvideClassInfo; if (provideClassInfo != null) { ITypeInfo tempTypeInfo; if (RawCOMHelpers.HResult.Succeeded(provideClassInfo.GetClassInfo(out tempTypeInfo))) { typeInfo = GetTypeForTypeInfo(tempTypeInfo); typeInfoKind = GetTypeInfoKind(tempTypeInfo); typeInfoFlags = GetTypeInfoFlags(tempTypeInfo); } } } } if (typeInfo != null) { // If the COM type is a dispatch-only interface, use it. Such interfaces typically // aren't exposed via QueryInterface(), so there's no way to validate them anyway. if ((dispatch != null) && (typeInfoKind == TYPEKIND.TKIND_DISPATCH) && typeInfoFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FDISPATCHABLE) && !typeInfoFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FDUAL)) { return(typeInfo); } // COM type information acquired in this manner may not actually be valid for the // original object. In some cases the original object implements a base interface. if (typeInfo.IsInstanceOfType(value)) { return(typeInfo); } foreach (var interfaceType in typeInfo.GetInterfaces()) { if (interfaceType.IsInstanceOfType(value)) { return(interfaceType); } } } return(type); }
private static void AppendTypeAttribute(DescriptionBuilder sb, TYPEATTR typeAttr, TYPEFLAGS attribute) { if ((typeAttr.wTypeFlags & attribute) == attribute) { sb.Append(", "); sb.Append(ComBrowserSettings.GetKeyword(attribute)); } }