/// <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); } }
// Returns the index of this object's type in the typelib protected int GetTypeLib(IntPtr dispPtr) { if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("ComObjInfo::GetTypeLib: " + _obj + " type: " + _obj.GetType()); } if (_typeLib != null) { return(-1); } UCOMITypeLib iTypeLib; int index = -1; try { IDispatch idisp = (IDispatch) Marshal.GetObjectForIUnknown(dispPtr); int count; int result = idisp.GetTypeInfoCount(out count); if (result != 0) { TraceUtil.WriteLineWarning (typeof(ComObjectInfo), "ComObjInfo - " + "GetTypeInfoCount failed: 0x" + result.ToString("x") + " obj: " + _obj); throw new COMException("(probably a bug, please report) " + "Failed on GetTypeInfoCount", result); } if (count == 0) { TraceUtil.WriteLineWarning (typeof(ComObjectInfo), "ComObjInfo - " + " typeinfo count = 0: " + _obj); throw new Exception("This object has no type information " + "(GetTypeInfoCount returned 0). "); } result = idisp.GetTypeInfo(0, 0, out _typeInfo); if (result != 0) { TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo - " + "typeInfo not found:" + _obj); throw new COMException("(probably a bug, please report) " + "Failed to get ITypeInfo", result); } if (_typeInfo == null) { TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo - " + "typeInfo not found:" + _obj); throw new Exception("(probably a bug, please report) " + "Null TypeInfo pointer returned"); } // Now we can get the type library information using these // nice interfaces provided as part of the interop services _typeInfo.GetContainingTypeLib(out iTypeLib, out index); _typeLib = TypeLibrary.GetTypeLib(iTypeLib); } catch (Exception ex) { if (_typeInfo != null) { Guid guid = BasicInfo.GuidFromTypeInfo(_typeInfo); TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo (type " + guid + ")"); } TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "Containing typelib not found:" + ex); throw new Exception("Cannot get TypeLib for object. " + "Getting the TypeLib information for " + "an object is required as this contains " + "the type information used to display " + "the object. ", ex); } if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("ComObjInfo - containing typelib index: " + index); } return(index); }