/// <summary>
        /// Gets the TypeName for objects implementing IDispatch.
        /// </summary>
        /// <param name="obj">The object for which to get the TypeName</param>
        /// <returns>String</returns>
        public static string GetIDispatchTypeName(IDispatch obj)
        {
            ITypeInfo t;

            obj.GetTypeInfo(0, 0, out t);

            return Marshal.GetTypeInfoName(t);
        }
示例#2
0
        public unsafe void ITypeInfo_GetFuncDesc_Invoke_Success()
        {
            using var image = new Bitmap(16, 32);
            IPictureDisp picture  = MockAxHost.GetIPictureDispFromPicture(image);
            IDispatch    dispatch = (IDispatch)picture;
            ITypeInfo    typeInfo;
            HRESULT      hr = dispatch.GetTypeInfo(0, Kernel32.GetThreadLocale(), out typeInfo);

            using var typeInfoReleaser = new ComRefReleaser(typeInfo);
            Assert.Equal(HRESULT.S_OK, hr);

            FUNCDESC *pFuncDesc = null;

            try
            {
                hr = typeInfo.GetFuncDesc(0, &pFuncDesc);
                Assert.Equal(HRESULT.S_OK, hr);
                Assert.Equal((DispatchID)6, pFuncDesc->memid);
                Assert.Equal(IntPtr.Zero, pFuncDesc->lprgscode);
                Assert.NotEqual(IntPtr.Zero, (IntPtr)pFuncDesc->lprgelemdescParam);
                Assert.Equal(FUNCKIND.DISPATCH, pFuncDesc->funckind);
                Assert.Equal(INVOKEKIND.FUNC, pFuncDesc->invkind);
                Assert.Equal(CALLCONV.STDCALL, pFuncDesc->callconv);
                Assert.Equal(10, pFuncDesc->cParams);
                Assert.Equal(0, pFuncDesc->cParamsOpt);
                Assert.Equal(0, pFuncDesc->oVft);
                Assert.Equal(0, pFuncDesc->cScodes);
                Assert.Equal(VARENUM.VOID, pFuncDesc->elemdescFunc.tdesc.vt);
                Assert.Equal(IntPtr.Zero, pFuncDesc->elemdescFunc.tdesc.union.lpadesc);
                Assert.Equal(IntPtr.Zero, pFuncDesc->elemdescFunc.paramdesc.pparamdescex);
                Assert.Equal(IntPtr.Zero, pFuncDesc->elemdescFunc.paramdesc.pparamdescex);
            }
            finally
            {
                typeInfo.ReleaseFuncDesc(pFuncDesc);
            }
        }
示例#3
0
        private static Type GetType(IDispatch dispatch, bool throwIfNotFound)
        {
            RequireReference(dispatch, "dispatch");

            Type result = null;
            int  typeInfoCount;
            int  hr = dispatch.GetTypeInfoCount(out typeInfoCount);

            if (hr == S_OK && typeInfoCount > 0)
            {
                dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
            }

            if (result == null && throwIfNotFound)
            {
                // If the GetTypeInfoCount called failed, throw an exception for that.
                Marshal.ThrowExceptionForHR(hr);

                // Otherwise, throw the same exception that Type.GetType would throw.
                throw new TypeLoadException();
            }

            return(result);
        }
示例#4
0
        public unsafe void ITypeInfo_GetTypeComp_Invoke_Success()
        {
            using var image = new Bitmap(16, 32);
            IPictureDisp picture  = MockAxHost.GetIPictureDispFromPicture(image);
            IDispatch    dispatch = (IDispatch)picture;
            ITypeInfo    typeInfo;
            HRESULT      hr = dispatch.GetTypeInfo(0, Kernel32.GetThreadLocale(), out typeInfo);

            using var typeInfoReleaser = new ComRefReleaser(typeInfo);
            Assert.Equal(HRESULT.S_OK, hr);

            IntPtr typeComp = IntPtr.Zero;

            hr = typeInfo.GetTypeComp(&typeComp);
            try
            {
                Assert.Equal(HRESULT.S_OK, hr);
                Assert.NotEqual(IntPtr.Zero, typeComp);
            }
            finally
            {
                Runtime.InteropServices.Marshal.Release(typeComp);
            }
        }
示例#5
0
        public unsafe void ITypeInfo_GetRefTypeInfo_Invoke_Success()
        {
            using var image = new Bitmap(16, 32);
            IPictureDisp picture  = MockAxHost.GetIPictureDispFromPicture(image);
            IDispatch    dispatch = (IDispatch)picture;
            ITypeInfo    typeInfo;
            HRESULT      hr = dispatch.GetTypeInfo(0, Kernel32.GetThreadLocale(), out typeInfo);

            using var typeInfoReleaser = new ComRefReleaser(typeInfo);
            Assert.Equal(HRESULT.S_OK, hr);

            uint refType = uint.MaxValue;

            hr = typeInfo.GetRefTypeOfImplType(0, &refType);
            Assert.Equal(HRESULT.S_OK, hr);
            Assert.NotEqual(0u, refType);

            ITypeInfo refTypeInfo;

            hr = typeInfo.GetRefTypeInfo(refType, out refTypeInfo);
            using var refTypeInfoReleaser = new ComRefReleaser(refTypeInfo);
            Assert.Equal(HRESULT.S_OK, hr);
            Assert.NotNull(refTypeInfo);
        }
示例#6
0
        /// <summary>
        /// Create a new COMTypeInformation object for the given COM Object.
        /// </summary>
        public COMTypeInformation(object comObject)
        {
            dispatch = comObject as IDispatch;
            if (dispatch == null)
            {
                throw new Exception("Object is not a COM Object");
            }
            int typeInfoCount;
            int hr = dispatch.GetTypeInfoCount(out typeInfoCount);

            if (hr < 0)
            {
                throw new COMException("GetTypeInfoCount failed", hr);
            }
            if (typeInfoCount != 1)
            {
                throw new Exception("No TypeInfo present");
            }
            hr = dispatch.GetTypeInfo(0, LCID_US_ENGLISH, out typeInfo);
            if (hr < 0)
            {
                throw new COMException("GetTypeInfo failed", hr);
            }
        }
示例#7
0
 public static ITypeInfo GetTypeInfo(this IDispatch dispatch)
 {
     return(dispatch.GetTypeInfo(0, NativeMethods.LOCALE_SYSTEM_DEFAULT));
 }
示例#8
0
        /// <summary>
        /// Returns a string value representing the type name of the specified COM object.
        /// </summary>
        /// <param name="comObj">A COM object the type name of which to return.</param>
        /// <returns>A string containing the type name.</returns>
        public static string GetTypeName(object comObj)
        {
            if (comObj == null)
            {
                return(String.Empty);
            }

            if (!Marshal.IsComObject(comObj))
            {
                //The specified object is not a COM object
                return(String.Empty);
            }

            IDispatch dispatch = comObj as IDispatch;

            if (dispatch == null)
            {
                //The specified COM object doesn't support getting type information
                return(String.Empty);
            }

            ComTypes.ITypeInfo typeInfo = null;
            try
            {
                try
                {
                    // obtain the ITypeInfo interface from the object
                    dispatch.GetTypeInfo(0, 0, out typeInfo);
                }
                catch (Exception ex)
                {
                    //Cannot get the ITypeInfo interface for the specified COM object
                    return(String.Empty);
                }

                string typeName = "";
                string documentation, helpFile;
                int    helpContext = -1;

                try
                {
                    //retrieves the documentation string for the specified type description
                    typeInfo.GetDocumentation(-1, out typeName, out documentation,
                                              out helpContext, out helpFile);
                }
                catch (Exception ex)
                {
                    // Cannot extract ITypeInfo information
                    return(String.Empty);
                }
                return(typeName);
            }
            catch (Exception ex)
            {
                // Unexpected error
                return(String.Empty);
            }
            finally
            {
                if (typeInfo != null)
                {
                    Marshal.ReleaseComObject(typeInfo);
                }
            }
        }
示例#9
0
        /// <summary>
        /// Creates an entity support list for a proxy
        /// </summary>
        /// <param name="factory">core to perform searching</param>
        /// <param name="comProxy">proxy to analyze</param>
        /// <returns>supported methods and properties as name/kind dictionary</returns>
        /// <exception cref="COMException">Throws generaly if any exception occurs. See inner exception(s) for details</exception>
        internal Dictionary <string, string> GetSupportedEntities(Core factory, object comProxy)
        {
            try
            {
                Guid parentLibraryGuid = CoreFactoryExtensions.GetParentLibraryGuid(factory, comProxy);
                if (Guid.Empty == parentLibraryGuid)
                {
                    return(null);
                }

                string className = TypeDescriptor.GetClassName(comProxy);
                string key       = (parentLibraryGuid.ToString() + className).ToLower();

                Dictionary <string, string> supportList = null;
                if (factory.EntitiesListCache.TryGetValue(key, out supportList))
                {
                    return(supportList);
                }

                supportList = new Dictionary <string, string>();
                IDispatch dispatch = comProxy as IDispatch;
                if (null == dispatch)
                {
                    throw new COMException("Unable to cast underlying proxy to IDispatch.");
                }

                COMTypes.ITypeInfo typeInfo = dispatch.GetTypeInfo(0, 0);
                if (null == typeInfo)
                {
                    throw new COMException("GetTypeInfo returns null.");
                }

                IntPtr typeAttrPointer = IntPtr.Zero;
                typeInfo.GetTypeAttr(out typeAttrPointer);

                COMTypes.TYPEATTR typeAttr = (COMTypes.TYPEATTR)Marshal.PtrToStructure(typeAttrPointer, typeof(COMTypes.TYPEATTR));
                for (int i = 0; i < typeAttr.cFuncs; i++)
                {
                    string            strName, strDocString, strHelpFile;
                    int               dwHelpContext;
                    IntPtr            funcDescPointer = IntPtr.Zero;
                    COMTypes.FUNCDESC funcDesc;
                    typeInfo.GetFuncDesc(i, out funcDescPointer);
                    funcDesc = (COMTypes.FUNCDESC)Marshal.PtrToStructure(funcDescPointer, typeof(COMTypes.FUNCDESC));

                    switch (funcDesc.invkind)
                    {
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYGET:
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYPUT:
                    case COMTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF:
                    {
                        typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile);
                        string outValue = "";
                        bool   exists   = supportList.TryGetValue("Property-" + strName, out outValue);
                        if (!exists)
                        {
                            supportList.Add("Property-" + strName, strDocString);
                        }
                        break;
                    }

                    case COMTypes.INVOKEKIND.INVOKE_FUNC:
                    {
                        typeInfo.GetDocumentation(funcDesc.memid, out strName, out strDocString, out dwHelpContext, out strHelpFile);
                        string outValue = "";
                        bool   exists   = supportList.TryGetValue("Method-" + strName, out outValue);
                        if (!exists)
                        {
                            supportList.Add("Method-" + strName, strDocString);
                        }
                        break;
                    }
                    }

                    typeInfo.ReleaseFuncDesc(funcDescPointer);
                }

                typeInfo.ReleaseTypeAttr(typeAttrPointer);
                Marshal.ReleaseComObject(typeInfo);

                factory.EntitiesListCache.Add(key, supportList);

                return(supportList);
            }
            catch (Exception exception)
            {
                throw new COMException("An unexpected error occurs.", exception);
            }
        }
示例#10
0
        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);
        }
示例#11
0
        // 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);
        }
示例#12
0
        private static ITypeInfo GetTypeInfo(IDispatch disp)
        {
            const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800

            return(disp.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT));
        }
示例#13
0
        public ComTypeInfo FromIDispatch(IDispatch dispatch)
        {
            if (dispatch == null) return null;

            return FromITypeInfo(dispatch.GetTypeInfo());
        }