static void ExtractNames(string typelib) { UCOMITypeLib tl = null; OleAut.LoadTypeLibEx(typelib, OleAut.REGKIND_NONE, out tl); // Get the names from ITypeLib string name; string docstring; Int32 ctxt; string helpfile; tl.GetDocumentation(-1, out name, out docstring, out ctxt, out helpfile); IntPtr pa; tl.GetLibAttr(out pa); TYPELIBATTR ta = (TYPELIBATTR)Marshal.PtrToStructure(pa, typeof(TYPELIBATTR)); DealWithName(name, ta.guid); // Enumerate TypeInfos int nTypeInfos = tl.GetTypeInfoCount(); for (int i = 0; i < nTypeInfos; i++) { UCOMITypeInfo it = null; tl.GetTypeInfo(i, out it); DealWithTypeInfo(it); } }
/// <summary> /// Gets the name of the default COM interface for this object. /// </summary> /// <remarks> /// Uses the COM ITypeInfo interface to get the information. Does not throw. /// </remarks> /// <param name="obj"></param> /// <returns>The name of the interface; null on any exception</returns> /// internal static string GetDefaultCOMInterfaceName(object obj) { try { string intfName = (string)Marshal.GetComObjectData(obj, "NETLinkCOMInterface"); if (intfName == null) { UCOMIDispatch iDisp = GetIDispatch(obj); UCOMITypeInfo iTypeInfo = GetITypeInfo(obj, iDisp); string typeLibName, docStr, helpFile; int helpContext; iTypeInfo.GetDocumentation(-1, out intfName, out docStr, out helpContext, out helpFile); UCOMITypeLib iTypeLib; int index; iTypeInfo.GetContainingTypeLib(out iTypeLib, out index); iTypeLib.GetDocumentation(-1, out typeLibName, out docStr, out helpContext, out helpFile); intfName = typeLibName + "." + intfName; Marshal.SetComObjectData(obj, "NETLinkCOMInterface", intfName); // Not strictly necessary to release here, but better to force it now than rely on GC to do it later. // Cannot release iDisp or iTypeInfo, as they might be cached in the object. Marshal.ReleaseComObject(iTypeLib); } return(intfName); } catch (Exception) { return(null); } }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { _typeLib = typeLib; _iTypeLib = typeLib.ITypeLib; if (typeInfo != null) { _typeInfo = typeInfo; } else { _iTypeLib.GetTypeInfo(index, out _typeInfo); } if (!guid.Equals(Guid.Empty)) { InitGuid(guid); } else { InitGuid(GuidFromTypeInfo(_typeInfo)); } _typeKind = typeKind; _presInfo = PresentationMap.GetInfo(_typeKind); GetDocumentation(index); if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine(this, "Basic: " + typeKind + " " + this); } }
protected void SetupTypeLibInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { if (_hasTypeLibInfo) { return; } base.Setup(typeLib, typeKind, index, typeInfo, guid); TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _cImplTypes = typeAttr.cImplTypes; _typeFlags = typeAttr.wTypeFlags; _typeInfo.ReleaseTypeAttr(typeAttrPtr); _hasTypeLibInfo = true; }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) : this() { Setup(typeLib, typeKind, index, typeInfo, guid); }
internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, bool dual) { IntPtr funcDescPtr; FUNCDESC funcDesc; ComMemberInfo comMemberInfo = null; typeInfo.GetFuncDesc(index, out funcDescPtr); funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC)); // from http://www.opengroup.org/onlinepubs/009899899/toc.htm // Table 25-43: MEMBERID Format // // Bits Value // 0 - 15 Offset. Any value is permissible. // 16 - 21 The nesting level of this type information // in the inheritance hierarchy. For example: // interface mydisp : IDispatch. // The nesting level of IUnknown() is 0, // IDispatch is 1, and MyDisp is 2. // 22 - 25 Reserved. Must be zero. // 26 - 28 Value of the DISPID. // 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE. // 30 - 31 Must be 01. // For a dispatch interface, show only those members that are // part of the user's definition, which is bits 16-17 == 2 // (as above); also only if this is a MEMBERID format (bit 30 on) // (some members just use the low order bits and the rest // are empty); also show any negative member Id. if (!dispatch || // ((Int16)funcDesc.memid < 0) || (funcDesc.memid & 0xFFFF) < 0 || (funcDesc.memid & 0x40000000) == 0 || (funcDesc.memid & 0x30000) == 0x20000) { comMemberInfo = new ComMemberInfo(parent, typeKind, typeInfo, index, dispatch, funcDesc); } else { if (TraceUtil.If(null, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: SKIPPING index: " + index + " memid: 0x" + funcDesc.memid.ToString("X")); } } typeInfo.ReleaseFuncDesc(funcDescPtr); return(comMemberInfo); }
// Constuctor when creating from withing a typelib protected ComClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { Init(); SetupTypeLibInfo(typeLib, typeKind, index, typeInfo, guid); _classesByCLSID.Add(_guid, this); }
// The TypeLibrary is used to resolve any typedefs public static String TYPEDESCToString(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType) { String ret = TYPEDESCToStringInt(typeLib, typeInfo, typeDesc, comType, 0); return ret; }
// The TypeLibrary is used to resolve any typedefs public static String TYPEDESCToString(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType) { String ret = TYPEDESCToStringInt(typeLib, typeInfo, typeDesc, comType, 0); return(ret); }
// Allows exceptions to be thrown. private static UCOMITypeInfo GetITypeInfo(object obj, UCOMIDispatch iDisp) { UCOMITypeInfo iTypeInfo = (UCOMITypeInfo)Marshal.GetComObjectData(obj, "NETLinkITypeInfo"); if (iTypeInfo == null) { iDisp.GetTypeInfo(0, GetUserDefaultLCID(), out iTypeInfo); Marshal.SetComObjectData(obj, "NETLinkITypeInfo", iTypeInfo); } return(iTypeInfo); }
internal static String GetTypeName(UCOMITypeInfo typeInfo) { String name; String dummy1 = null; int dummy2 = 0; String dummy3 = null; typeInfo.GetDocumentation(-1, out name, out dummy1, out dummy2, out dummy3); return(name); }
internal static ComMemberInfo MakeComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, bool dual) { IntPtr funcDescPtr; FUNCDESC funcDesc; ComMemberInfo comMemberInfo = null; typeInfo.GetFuncDesc(index, out funcDescPtr); funcDesc = (FUNCDESC)Marshal.PtrToStructure(funcDescPtr, typeof(FUNCDESC)); // from http://www.opengroup.org/onlinepubs/009899899/toc.htm // Table 25-43: MEMBERID Format // // Bits Value // 0 - 15 Offset. Any value is permissible. // 16 - 21 The nesting level of this type information // in the inheritance hierarchy. For example: // interface mydisp : IDispatch. // The nesting level of IUnknown() is 0, // IDispatch is 1, and MyDisp is 2. // 22 - 25 Reserved. Must be zero. // 26 - 28 Value of the DISPID. // 29 TRUE if this is the member ID for a FUNCDESC; otherwise FALSE. // 30 - 31 Must be 01. // For a dispatch interface, show only those members that are // part of the user's definition, which is bits 16-17 == 2 // (as above); also only if this is a MEMBERID format (bit 30 on) // (some members just use the low order bits and the rest // are empty); also show any negative member Id. if (!dispatch || // ((Int16)funcDesc.memid < 0) || (funcDesc.memid & 0xFFFF) < 0 || (funcDesc.memid & 0x40000000) == 0 || (funcDesc.memid & 0x30000) == 0x20000) { comMemberInfo = new ComMemberInfo(parent, typeKind, typeInfo, index, dispatch, funcDesc); } else { if (TraceUtil.If(null, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: SKIPPING index: " + index + " memid: 0x" + funcDesc.memid.ToString("X")); } } typeInfo.ReleaseFuncDesc(funcDescPtr); return comMemberInfo; }
// Can't return the TYPEATTR struct because there is no // way to free it, better to have methods get the parts that // are needed. internal static Guid GuidFromTypeInfo(UCOMITypeInfo typeInfo) { Guid guid; TYPEATTR typeAttr; IntPtr typeAttrPtr; typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); guid = typeAttr.guid; typeInfo.ReleaseTypeAttr(typeAttrPtr); return(guid); }
/// <summary> /// Like Marshal.ReleaseCOMObject, but also frees IDispatch and ITypeInfo objects held in the object's cache. /// </summary> /// <param name="obj"></param> /// <returns>The new COM refcount.</returns> /// internal static int releaseCOMObject(object obj) { int newRefCount = Marshal.ReleaseComObject(obj); if (newRefCount == 0) { UCOMITypeInfo iTypeInfo = (UCOMITypeInfo)Marshal.GetComObjectData(obj, "NETLinkITypeInfo"); if (iTypeInfo != null) { Marshal.ReleaseComObject(iTypeInfo); } UCOMIDispatch iDisp = (UCOMIDispatch)Marshal.GetComObjectData(obj, "NETLinkIDispatch"); if (iDisp != null) { Marshal.ReleaseComObject(iDisp); } } return(newRefCount); }
static void DealWithTypeInfo(UCOMITypeInfo it) { // Get the names from ITypeInfo string name; string docstring; Int32 ctxt; string helpfile; // TypeInfo name it.GetDocumentation(-1, out name, out docstring, out ctxt, out helpfile); IntPtr pa; it.GetTypeAttr(out pa); TYPEATTR ta = (TYPEATTR)Marshal.PtrToStructure(pa, typeof(TYPEATTR)); DealWithName(name, ta.guid); // Deal with funcs for (int i = 0; i < ta.cFuncs; i++) { IntPtr pfd; it.GetFuncDesc(i, out pfd); FUNCDESC fd = (FUNCDESC)Marshal.PtrToStructure(pfd, typeof(FUNCDESC)); it.GetDocumentation(fd.memid, out name, out docstring, out ctxt, out helpfile); DealWithName(name, Guid.Empty); } // Deal with vars for (int i = 0; i < ta.cVars; i++) { IntPtr pvd; it.GetVarDesc(i, out pvd); VARDESC vd = (VARDESC)Marshal.PtrToStructure(pvd, typeof(VARDESC)); it.GetDocumentation(vd.memid, out name, out docstring, out ctxt, out helpfile); DealWithName(name, Guid.Empty); } }
public static string GetTypeInfoName (UCOMITypeInfo pTI) { throw new NotImplementedException (); }
public static String TYPEDESCToStringInt(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType, int level) { String ret; try { if ((VarEnum)typeDesc.vt == VarEnum.VT_PTR || (VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { TYPEDESC pTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pTypeDesc, comType, level + 1); if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { // FIXME - what about the non-comType return("SAFEARRAY(" + ret + ")"); } if (comType) { ret += "*"; } else { // void* become IntPtr if (ret.Equals("void")) { ret = "System.IntPtr"; } else { // The first pointer is not a ref, its only // a ref if there are two // FIXME - what if there are more? if (level == 1) { ret = "ref " + ret; } } } return(ret); } if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_CARRAY) { // typeDesc.lpValue in this case is really the laValue // (since TYPEDESC is a contains a union of pointers) ARRAYDESC pArrayDesc = (ARRAYDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(ARRAYDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pArrayDesc.tdescElem, comType, level + 1); // Just show the number of diminsions, don't worry about // showing the size of each since we don't want to // get into marshalling the variable length ARRAYDESC // structure for (int i = 0; i < pArrayDesc.cDims; i++) { ret += "[]"; } return(ret); } if ((VarEnum)typeDesc.vt == VarEnum.VT_USERDEFINED) { UCOMITypeInfo uTypeInfo = null; // FIXME - sometimes this chokes and hangs due to a bad // handle value here, need to do something to prevent this int href = typeDesc.lpValue.ToInt32(); typeInfo.GetRefTypeInfo(href, out uTypeInfo); if (uTypeInfo != null) { String docName; String docString; int helpContext; String helpFile; uTypeInfo.GetDocumentation(-1, out docName, out docString, out helpContext, out helpFile); // Fix up misc references if (docName.Equals("GUID")) { docName = "System.Guid"; } // Present the user names for the types in COM // mode, but for the CLR types, get the real // underlying names if (!comType) { return(typeLib.ResolveTypeDef(docName, comType)); } return(docName); } else { TraceUtil.WriteLineWarning(null, "USER: "******" 0x" + href.ToString("X") + " ***UNKNOWN***"); return("(userDef unknown)"); } } return(GetTypeStr(typeDesc.vt, comType)); } catch (Exception ex) { TraceUtil.WriteLineWarning (null, "ActiveX type conversion error: " + ex); return("(error)"); } }
public static string GetTypeInfoName(UCOMITypeInfo pTI) {}
public static String TYPEDESCToStringInt(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType, int level) { String ret; try { if ((VarEnum)typeDesc.vt == VarEnum.VT_PTR || (VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { TYPEDESC pTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pTypeDesc, comType, level + 1); if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { // FIXME - what about the non-comType return "SAFEARRAY(" + ret + ")"; } if (comType) { ret += "*"; } else { // void* become IntPtr if (ret.Equals("void")) ret = "System.IntPtr"; else { // The first pointer is not a ref, its only // a ref if there are two // FIXME - what if there are more? if (level == 1) ret = "ref " + ret; } } return ret; } if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_CARRAY) { // typeDesc.lpValue in this case is really the laValue // (since TYPEDESC is a contains a union of pointers) ARRAYDESC pArrayDesc = (ARRAYDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(ARRAYDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pArrayDesc.tdescElem, comType, level + 1); // Just show the number of diminsions, don't worry about // showing the size of each since we don't want to // get into marshalling the variable length ARRAYDESC // structure for (int i = 0; i < pArrayDesc.cDims; i++) ret += "[]"; return ret; } if ((VarEnum)typeDesc.vt == VarEnum.VT_USERDEFINED) { UCOMITypeInfo uTypeInfo = null; // FIXME - sometimes this chokes and hangs due to a bad // handle value here, need to do something to prevent this int href = typeDesc.lpValue.ToInt32(); typeInfo.GetRefTypeInfo(href, out uTypeInfo); if (uTypeInfo != null) { String docName; String docString; int helpContext; String helpFile; uTypeInfo.GetDocumentation(-1, out docName, out docString, out helpContext, out helpFile); // Fix up misc references if (docName.Equals("GUID")) docName = "System.Guid"; // Present the user names for the types in COM // mode, but for the CLR types, get the real // underlying names if (!comType) return typeLib.ResolveTypeDef(docName, comType); return docName; } else { TraceUtil.WriteLineWarning(null, "USER: "******" 0x" + href.ToString("X") + " ***UNKNOWN***"); return "(userDef unknown)"; } } return GetTypeStr(typeDesc.vt, comType); } catch (Exception ex) { TraceUtil.WriteLineWarning (null, "ActiveX type conversion error: " + ex); return "(error)"; } }
// Used for member subclasses internal BasicInfo(UCOMITypeInfo typeInfo) : this() { _typeInfo = typeInfo; }
internal ComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, FUNCDESC funcDesc) : base(typeInfo) { int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(funcDesc.memid, memberNames, memberNames.Length, out actLen); _memberId = funcDesc.memid; // the high order part of the memberId is flags // for a dispatch interface if (dispatch) { _memberId &= 0xffff; // Make sure we get a 16 bit integer so that negative // DISPIDs show up correctly _memberId = (Int16)_memberId; } String docString; // Note, use the original unmasked memberId _typeInfo.GetDocumentation(funcDesc.memid, out _name, out docString, out _helpContext, out _helpFile); // Set using property so that nulls are checked DocString = docString; _parameters = new ArrayList(); _typeLib = parent.TypeLib; _index = index; _container = parent; _printName = _name; _nameKey = (String)_name; // Add the DISPID to the dispatch interfaces if (dispatch) { _dispatch = true; _printName += " - " + _memberId; } if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("MemberInfo: " + _name); } _type = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, funcDesc.elemdescFunc.tdesc, TypeLibUtil.COMTYPE); if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC) { _infoType = "Function"; _property = false; if (funcDesc.cParams > 0) { AddParams(funcDesc, memberNames, funcDesc.cParams); } } else { if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET) { _printName += " (get)"; _nameKey += NAMEKEY_GET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT) { _printName += " (put)"; _nameKey += NAMEKEY_SET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF) { _printName += " (put ref)"; _nameKey += NAMEKEY_SETREF; } _infoType = "Property"; _property = true; } _flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags); if (_property) { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_PROPERTY); } else { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_METHOD); } }
public static string GetTypeInfoName(UCOMITypeInfo pTI) { return default(string); }
public static string GetTypeInfoName(UCOMITypeInfo pTI) { // // Summary: // Retrieves the library identifier (LIBID) of a type library. // // Parameters: // typelib: // An System.Runtime.InteropServices.ComTypes.ITypeLib object that represents // an ITypeLib pointer. // // Returns: // The LIBID (that is, the System.Guid) of the type library pointed to by the // typelib parameter. return default(string); }
// Can't return the TYPEATTR struct because there is no // way to free it, better to have methods get the parts that // are needed. internal static Guid GuidFromTypeInfo(UCOMITypeInfo typeInfo) { Guid guid; TYPEATTR typeAttr; IntPtr typeAttrPtr; typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); guid = typeAttr.guid; typeInfo.ReleaseTypeAttr(typeAttrPtr); return guid; }
protected void SetupTypeLibInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { if (_hasTypeLibInfo) return; base.Setup(typeLib, typeKind, index, typeInfo, guid); TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _cImplTypes = typeAttr.cImplTypes; _typeFlags = typeAttr.wTypeFlags; _typeInfo.ReleaseTypeAttr(typeAttrPtr); _hasTypeLibInfo = true; }
internal ComVariableInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index) : base(typeInfo) { IntPtr varDescPtr; CORRECT_VARDESC varDesc; _typeKind = typeKind; _typeLib = parent.TypeLib; _container = parent; _index = index; _typeInfo.GetVarDesc(_index, out varDescPtr); varDesc = (CORRECT_VARDESC) Marshal.PtrToStructure(varDescPtr, typeof(CORRECT_VARDESC)); int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(varDesc.memid, memberNames, memberNames.Length, out actLen); Name = memberNames[0]; if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("VariableInfo: " + _name); if (_typeKind == TYPEKIND.TKIND_ENUM) { _infoType = "Constant"; try { Object value = Marshal.GetObjectForNativeVariant (varDesc.u.lpvarValue); _enumValue = value.ToString(); } catch (Exception ex) { _enumValue = "Unknown variant: 0x" + varDesc.u.lpvarValue.ToInt32().ToString("X"); TraceUtil.WriteLineWarning(this, "Exception reading enum value: " + ex); } } else { _infoType = "Variable"; } TYPEDESC typeDesc = varDesc.elemdescVar.tdesc; _varType = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, typeDesc, TypeLibUtil.COMTYPE); _typeInfo.ReleaseVarDesc(varDescPtr); _presInfo = PresentationMap. GetInfo(PresentationMap.COM_VARIABLE); }
// Used for member subclasses internal BasicInfo(UCOMITypeInfo typeInfo) : this() { _typeInfo = typeInfo; }
private string GetClassName(UCOMITypeInfo typeInfo) { UCOMITypeInfo2 typeInfo2 = (UCOMITypeInfo2)typeInfo; object custData = new object(); Guid g = new Guid("0F21F359-AB84-41E8-9A78-36D110E6D2F9"); typeInfo2.GetCustData(ref g, out custData); return (string)custData; }
private TYPEATTR GetTypeAttributes(UCOMITypeInfo typeInfo) { IntPtr pTypeAttr = new IntPtr(0); typeInfo.GetTypeAttr(out pTypeAttr); TYPEATTR typeAttr = (TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(TYPEATTR)); return typeAttr; }
/// <summary> /// Gets parameter information for the given member. /// </summary> /// <remarks> /// Uses the COM ITypeInfo interface to get the information. Does not throw. If it returns false then the out params /// will not hold useful information. /// </remarks> /// <param name="obj"></param> /// <param name="memberName"></param> /// <param name="callType"></param> /// <param name="isBeingCalledWithZeroArgs"></param> /// <param name="paramTypes"></param> /// <param name="paramFlags"></param> /// <param name="endsWithParamArray"></param> /// <returns>true if the name refers to a valid member or if no type information is available</returns> /// internal static bool GetMemberInfo(object obj, ref string memberName, int callType, bool isBeingCalledWithZeroArgs, out Type[] paramTypes, out PARAMFLAG[] paramFlags, out bool endsWithParamArray) { // There are some early returns in this method, so we initialize the out params right away. To the caller, if these values // come back null it means that the information could not be determined. paramTypes = null; paramFlags = null; endsWithParamArray = false; int defaultLCID = GetUserDefaultLCID(); try { // Throws in this outer try cause true to be returned. They mean "type info could not be obtained, so the member is not // known to be invalid." UCOMIDispatch iDisp = GetIDispatch(obj); int memberDispId = GetMemberDispID(obj, iDisp, ref memberName); if (memberDispId == -1) { // Name not found by GetIDsOfNames. return(false); } // If no args are being passed, then we can skip all the machinations below about type info. if (isBeingCalledWithZeroArgs) { return(true); } UCOMITypeInfo iTypeInfo = GetITypeInfo(obj, iDisp); IntPtr pFuncDesc; // Check to see if the func index for this member name is already cached from a previous call. FuncIndexHolder fih = (FuncIndexHolder)Marshal.GetComObjectData(obj, "NETLinkFuncIndex" + memberName); if (fih == null) { // This will be populated below. fih = new FuncIndexHolder(); Marshal.SetComObjectData(obj, "NETLinkFuncIndex" + memberName, fih); } int funcIndex = -1; if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_GET) { if (fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET != -1) { funcIndex = fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET; } } else if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_SET || callType == Install.CALLTYPE_PARAM_PROP_SET) { if (fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET != -1) { funcIndex = fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET; } } else if (callType == Install.CALLTYPE_METHOD || callType == Install.CALLTYPE_PARAM_PROP_GET) { // COM objects are treated by M code as if they all have indexers, so calls like obj[1] will // come in as CALLTYPE_PARAM_PROP_GET with a property name of Item. We can just treat these like // method calls. if (fih.funcIndexForCALLTYPE_METHOD != -1) { funcIndex = fih.funcIndexForCALLTYPE_METHOD; } } // Did not have the func index for this call type cached. if (funcIndex == -1) { IntPtr pTypeAttr; iTypeInfo.GetTypeAttr(out pTypeAttr); TYPEATTR typeAttr = (TYPEATTR)Marshal.PtrToStructure(pTypeAttr, typeof(TYPEATTR)); int numFuncs = typeAttr.cFuncs; iTypeInfo.ReleaseTypeAttr(pTypeAttr); bool foundDispId = false; for (int thisIndex = 0; thisIndex < numFuncs; thisIndex++) { // Be aware that GetFuncDesc() can (I think) throw a cryptic "Element not found" exception, // such as for a hidden property like (Excel) _Application.ActiveDialog. iTypeInfo.GetFuncDesc(thisIndex, out pFuncDesc); FUNCDESC funcDesc = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC)); int thisMemberId = funcDesc.memid; INVOKEKIND invokeKind = funcDesc.invkind; iTypeInfo.ReleaseFuncDesc(pFuncDesc); if (thisMemberId == memberDispId) { foundDispId = true; // Verify that it is a member of the correct call type. if (callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_GET && invokeKind == INVOKEKIND.INVOKE_PROPERTYGET) { fih.funcIndexForCALLTYPE_FIELD_OR_SIMPLE_PROP_GET = thisIndex; funcIndex = thisIndex; break; } else if ((callType == Install.CALLTYPE_FIELD_OR_SIMPLE_PROP_SET || callType == Install.CALLTYPE_PARAM_PROP_SET) && (invokeKind == INVOKEKIND.INVOKE_PROPERTYPUT || invokeKind == INVOKEKIND.INVOKE_PROPERTYPUTREF)) { fih.funcIndexForCALLTYPE_FIELD_OR_ANY_PROP_SET = thisIndex; funcIndex = thisIndex; break; } else if ((callType == Install.CALLTYPE_METHOD && (invokeKind == INVOKEKIND.INVOKE_FUNC || invokeKind == INVOKEKIND.INVOKE_PROPERTYGET)) || (callType == Install.CALLTYPE_PARAM_PROP_GET && invokeKind == INVOKEKIND.INVOKE_PROPERTYGET)) { // Parameterized prop gets, not sets, look like CALLTYPE_METHOD. Also, as discussed in an earlier comment, // indexer notation calls (obj[1]) are supported for all COM objects and come in as CALLTYPE_PARAM_PROP_GET. fih.funcIndexForCALLTYPE_METHOD = thisIndex; funcIndex = thisIndex; break; } } } if (funcIndex == -1) { // We didn't find the member in our search. This can happen in two ways. First, the member might // exist but not be the right call type. For this case we want to return false. Second, we didn't // even find the dispid. This can happen in unusual cases I don't understan An example of this // is the IWebBrowser2 interface obtained by CreateCOMObject["InternetExplorer.Application"]. // For this case we want to return true, as if there was no type info at all available, so the // call can still proceed. return(!foundDispId); } } // If we get to here, we have a valid funcIndex and memberDispId, and the member is of the correct variety // that corresponds to how it was called (e.g., it's a method and it was called as such). All that // remains is to get the parameter types. iTypeInfo.GetFuncDesc(funcIndex, out pFuncDesc); try { FUNCDESC funcDesc = (FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(FUNCDESC)); Debug.Assert(funcDesc.memid == memberDispId); int paramCount = funcDesc.cParams; // Functions that end with a VB-style ParamArray (a variable-length argument sequence) have -1 for the // cParamsOpt member. It is convenient to treat them specially, hence the 'endsWithParamArray' variable // (which is an out param for this method). The special treatment involves leaving the ParamArray arg off // the list of paramFlags and paramTypes. We just pretend there is one less arg to the function but // record that it ends with a ParamArray. We always know the type of this arg anyway: ByRef Variant[]. // To the caller, though, the individual args are sent as a sequence, not packed into an array. endsWithParamArray = funcDesc.cParamsOpt == -1; if (endsWithParamArray) { paramCount--; } paramTypes = new Type[paramCount]; paramFlags = new PARAMFLAG[paramCount]; IntPtr pElemDescArray = funcDesc.lprgelemdescParam; for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) { ELEMDESC elemDesc = (ELEMDESC)Marshal.PtrToStructure((IntPtr)(pElemDescArray.ToInt64() + paramIndex * Marshal.SizeOf(typeof(ELEMDESC))), typeof(ELEMDESC)); TYPEDESC typeDesc = elemDesc.tdesc; paramFlags[paramIndex] = elemDesc.desc.paramdesc.wParamFlags; // I think I should never see a retval param here. They have been automatically converted to return types. Debug.Assert((paramFlags[paramIndex] & PARAMFLAG.PARAMFLAG_FRETVAL) == 0); VarEnum variantType = (VarEnum)typeDesc.vt; bool isArray = variantType == VarEnum.VT_SAFEARRAY; bool isPtr = variantType == VarEnum.VT_PTR; bool isOut = (paramFlags[paramIndex] & PARAMFLAG.PARAMFLAG_FOUT) != 0; // VB array params will have isPtr and !isArray, because they are always ByRef (thus ptrs). // In general (always?), out params will be VT_PTR. if (isArray || isPtr) { IntPtr pElementTypeDesc = typeDesc.lpValue; TYPEDESC elementTypeDesc = (TYPEDESC)Marshal.PtrToStructure(pElementTypeDesc, typeof(TYPEDESC)); variantType = (VarEnum)elementTypeDesc.vt; // If the arg was a ptr to an array (e.g., as in VB objects), do it again to get the element type. if (variantType == VarEnum.VT_SAFEARRAY) { isArray = true; pElementTypeDesc = elementTypeDesc.lpValue; elementTypeDesc = (TYPEDESC)Marshal.PtrToStructure(pElementTypeDesc, typeof(TYPEDESC)); variantType = (VarEnum)elementTypeDesc.vt; } } paramTypes[paramIndex] = managedTypeForVariantType(variantType, isArray, isPtr, isOut); } } finally { iTypeInfo.ReleaseFuncDesc(pFuncDesc); } return(true); } catch (Exception) { return(true); } }
public static string GetTypeInfoName(UCOMITypeInfo pTI) { }
public static string GetTypeInfoName(UCOMITypeInfo pTI) { throw new NotImplementedException(); }
internal ComVariableInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index) : base(typeInfo) { IntPtr varDescPtr; CORRECT_VARDESC varDesc; _typeKind = typeKind; _typeLib = parent.TypeLib; _container = parent; _index = index; _typeInfo.GetVarDesc(_index, out varDescPtr); varDesc = (CORRECT_VARDESC) Marshal.PtrToStructure(varDescPtr, typeof(CORRECT_VARDESC)); int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(varDesc.memid, memberNames, memberNames.Length, out actLen); Name = memberNames[0]; if (TraceUtil.If(this, TraceLevel.Verbose)) { Trace.WriteLine("VariableInfo: " + _name); } if (_typeKind == TYPEKIND.TKIND_ENUM) { _infoType = "Constant"; try { Object value = Marshal.GetObjectForNativeVariant (varDesc.u.lpvarValue); _enumValue = value.ToString(); } catch (Exception ex) { _enumValue = "Unknown variant: 0x" + varDesc.u.lpvarValue.ToInt32().ToString("X"); TraceUtil.WriteLineWarning(this, "Exception reading enum value: " + ex); } } else { _infoType = "Variable"; } TYPEDESC typeDesc = varDesc.elemdescVar.tdesc; _varType = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, typeDesc, TypeLibUtil.COMTYPE); _typeInfo.ReleaseVarDesc(varDescPtr); _presInfo = PresentationMap. GetInfo(PresentationMap.COM_VARIABLE); }
internal static String GetTypeName(UCOMITypeInfo typeInfo) { String name; String dummy1 = null; int dummy2 = 0; String dummy3 = null; typeInfo.GetDocumentation(-1, out name, out dummy1, out dummy2, out dummy3); return name; }
internal ComMemberInfo(BasicInfo parent, TYPEKIND typeKind, UCOMITypeInfo typeInfo, int index, bool dispatch, FUNCDESC funcDesc) : base(typeInfo) { int actLen; String[] memberNames = new String[100]; _typeInfo.GetNames(funcDesc.memid, memberNames, memberNames.Length, out actLen); _memberId = funcDesc.memid; // the high order part of the memberId is flags // for a dispatch interface if (dispatch) { _memberId &= 0xffff; // Make sure we get a 16 bit integer so that negative // DISPIDs show up correctly _memberId = (Int16)_memberId; } String docString; // Note, use the original unmasked memberId _typeInfo.GetDocumentation(funcDesc.memid, out _name, out docString, out _helpContext, out _helpFile); // Set using property so that nulls are checked DocString = docString; _parameters = new ArrayList(); _typeLib = parent.TypeLib; _index = index; _container = parent; _printName = _name; _nameKey = (String)_name; // Add the DISPID to the dispatch interfaces if (dispatch) { _dispatch = true; _printName += " - " + _memberId; } if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("MemberInfo: " + _name); _type = TypeLibUtil.TYPEDESCToString (_typeLib, _typeInfo, funcDesc.elemdescFunc.tdesc, TypeLibUtil.COMTYPE); if (funcDesc.invkind == INVOKEKIND.INVOKE_FUNC) { _infoType = "Function"; _property = false; if (funcDesc.cParams > 0) { AddParams(funcDesc, memberNames, funcDesc.cParams); } } else { if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYGET) { _printName += " (get)"; _nameKey += NAMEKEY_GET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUT) { _printName += " (put)"; _nameKey += NAMEKEY_SET; } else if (funcDesc.invkind == INVOKEKIND.INVOKE_PROPERTYPUTREF) { _printName += " (put ref)"; _nameKey += NAMEKEY_SETREF; } _infoType = "Property"; _property = true; } _flagsString = FlagsString((FUNCFLAGS)funcDesc.wFuncFlags); if (_property) { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_PROPERTY); } else { _presInfo = PresentationMap. GetInfo(PresentationMap.COM_METHOD); } }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) : this() { Setup(typeLib, typeKind, index, typeInfo, guid); }
public static string GetTypeInfoName(UCOMITypeInfo pTI) { return(default(string)); }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { _typeLib = typeLib; _iTypeLib = typeLib.ITypeLib; if (typeInfo != null) _typeInfo = typeInfo; else _iTypeLib.GetTypeInfo(index, out _typeInfo); if (!guid.Equals(Guid.Empty)) InitGuid(guid); else InitGuid(GuidFromTypeInfo(_typeInfo)); _typeKind = typeKind; _presInfo = PresentationMap.GetInfo(_typeKind); GetDocumentation(index); if (TraceUtil.If(this, TraceLevel.Info)) Trace.WriteLine(this, "Basic: " + typeKind + " " + this); }
// Constuctor when creating from withing a typelib protected ComClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { Init(); SetupTypeLibInfo(typeLib, typeKind, index, typeInfo, guid); _classesByCLSID.Add(_guid, this); }