Beispiel #1
0
        /// <summary>
        /// Gets the full typename of an object
        /// In the case of .NET objects it is in the form 'Type.Namespace'.'Type.Name'
        /// In the case of COM objects it is in the form 'TypeLibName'.'TypeInfoName'
        /// </summary>
        /// <param name="obj">The object to get the full typename of</param>
        /// <returns>The full type name</returns>
        private string GetObjectFullTypeName(object obj)
        {
            if (Marshal.IsComObject(obj))
            {
                IDispatch dispatch = (IDispatch)obj;
                if (dispatch.GetTypeInfoCount() != 1)
                {
                    throw new Exception("Failed to get runtime type information");
                }

                ITypeInfo typeInfo = dispatch.GetTypeInfo(0, 0);

                ITypeLib typeLib;
                int      index;
                typeInfo.GetContainingTypeLib(out typeLib, out index);

                string typeLibName  = Marshal.GetTypeLibName(typeLib);
                string typeInfoName = Marshal.GetTypeInfoName(typeInfo);

                return(typeLibName + "." + typeInfoName);
            }
            else
            {
                Type typeObject = obj.GetType();
                return(typeObject.Namespace + "." + typeObject.Name);
            }
        }
        /// <summary>
        /// Gets a Type that can be used with reflection.
        /// </summary>
        /// <param name="dispatch">An object that implements IDispatch.</param>
        /// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
        /// <returns>A .NET Type that can be used with reflection.</returns>
        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)
            {
                // Type info isn't usually culture-aware for IDispatch, so we might as well pass
                // the default locale instead of looking up the current thread's LCID each time
                // (via CultureInfo.CurrentCulture.LCID).
                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);
        }
Beispiel #3
0
        public unsafe void IDispatch_GetTypeInfoCount_Invoke_Success()
        {
            using var image = new Bitmap(16, 16);
            IPictureDisp picture  = MockAxHost.GetIPictureDispFromPicture(image);
            IDispatch    dispatch = (IDispatch)picture;

            uint    ctInfo = uint.MaxValue;
            HRESULT hr     = dispatch.GetTypeInfoCount(&ctInfo);

            Assert.Equal(HRESULT.S_OK, hr);
            Assert.Equal(1u, ctInfo);
        }
Beispiel #4
0
        public static ITypeInfo GetTypeInfo(this IDispatch dispatch)
        {
            uint count;

            if (HResult.Succeeded(dispatch.GetTypeInfoCount(out count)) && (count > 0))
            {
                ITypeInfo typeInfo;
                if (HResult.Succeeded(dispatch.GetTypeInfo(0, 0, out typeInfo)))
                {
                    return(typeInfo);
                }
            }

            return(null);
        }
Beispiel #5
0
        private void AddInterfaces(ICallerContext context)
        {
            IDispatch dispatch = obj as IDispatch;

            if (dispatch == null)
            {
                // We have to treat it just as __ComObject
                AddInterfaces(context, obj.GetType().GUID, new IntPtr());
                return;
            }

            uint typeCount;

            dispatch.GetTypeInfoCount(out typeCount);
            if (typeCount > 0)
            {
                this.interfaces = new ArrayList();
                for (uint index = 0; index < typeCount; index++)
                {
                    IntPtr typeInfoPtr;
                    try {
                        dispatch.GetTypeInfo(index, 0, out typeInfoPtr);
                    } catch (COMException e) {
                        // This must be a registration-free COM object
                        Debug.Assert(e.ErrorCode == TYPE_E_LIBNOTREGISTERED);
                        continue;
                    }

                    try {
                        Guid guid = GetITypeInfoGuid(typeInfoPtr);
                        AddInterfaces(context, guid, typeInfoPtr);
                    } finally {
                        Marshal.Release(typeInfoPtr);
                    }
                }
            }
            else
            {
                // We have to treat it just as __ComObject
                AddInterfaces(context, obj.GetType().GUID, new IntPtr());
            }
        }
Beispiel #6
0
        public static void GetTypeInterfaceName(object comObject, out ComTypes.ITypeInfo comObjectTypeInformation, out string interfaceName)
        {
            comObjectTypeInformation = null;
            interfaceName            = null;

            IDispatch comObjectAsDispatch = comObject as IDispatch;

            if (comObjectAsDispatch == null)
            {
                return;
            }
            if (comObjectAsDispatch.GetTypeInfoCount() != 1)
            {
                return;
            }

            //Get the interface name
            comObjectTypeInformation = comObjectAsDispatch.GetTypeInfo(0, 0);
            interfaceName            = Marshal.GetTypeInfoName(comObjectTypeInformation);
        }
Beispiel #7
0
        public static ITypeInfo GetType(IDispatch dispatch, bool throwIfNotFound = false)
        {
            Guard.ArgumentNotNull(dispatch, "dispatch");

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

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

            if (result == null && throwIfNotFound)
            {
                Marshal.ThrowExceptionForHR((int)hr);
                throw new TypeLoadException();
            }

            return(result);
        }
Beispiel #8
0
        static void Main(string[] args)
        {
            IDispatch disp = (IDispatch)(new Printer());

            int a = 0;

            disp.GetTypeInfoCount(out a);
            var id = new int[6];

            disp.GetIDsOfNames(new Guid(), new string[] { "SetPetName", "DisplayStats", "SetMaxSpeed", "GetMaxSpeed", "GetCurSpeed", "SpeedUp" },
                               6, 1, id);

            var pParam = Marshal.AllocCoTaskMem(15);

            Marshal.GetNativeVariantForObject("HP", pParam);
            object res = 0;

            System.Runtime.InteropServices.ComTypes.DISPPARAMS param = new System.Runtime.InteropServices.ComTypes.DISPPARAMS()
            {
                cArgs             = 1,
                cNamedArgs        = 0,
                rgdispidNamedArgs = IntPtr.Zero,
                rgvarg            = pParam
            };
            disp.Invoke(id[0], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            Marshal.GetNativeVariantForObject("20", pParam);
            param.rgvarg = pParam;
            disp.Invoke(id[2], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            disp.Invoke(id[1], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            disp.Invoke(id[4], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            Console.WriteLine("Cur speed = " + res.ToString());
            disp.Invoke(id[5], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            disp.Invoke(id[4], new Guid(), 1, new System.Runtime.InteropServices.ComTypes.INVOKEKIND(), param, out res, new IntPtr(), new IntPtr());
            Console.WriteLine("Cur speed = " + res.ToString());

            Console.ReadKey();
        }
Beispiel #9
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);
        }
Beispiel #10
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);
            }
        }
Beispiel #11
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);
        }
Beispiel #12
0
        static void Main(string[] args)
        {
            object Res = 1;

            int a     = 0;
            Car myCar = new Car();
            //Type type = typeof(Car);
            ICreateCar iCrCar = (ICreateCar)myCar;
            IStats     iStCar = (IStats)myCar;

            //Console.WriteLine("Напишите имя: ");
            //iCrCar.SetPetName(Console.ReadLine());
            //IStats iStCar = (IStats)myCar;
            //string st = "";
            //iStCar.GetPetName(ref st);
            //Console.WriteLine(st);
            iCrCar.SetPetName("Lolipop");
            iCrCar.SetMaxSpeed(67);
            IDispatch disp = (IDispatch)myCar;

            iStCar.DisplayStats();
            disp.GetTypeInfoCount(out a);

            Console.WriteLine(a.ToString());

            int[] t    = new int[1];
            Guid  guid = new Guid();

            disp.GetIDsOfNames(ref guid, new string[] { "GetMaxSpeed" }, 1, 1, t);
            Console.WriteLine("Max speed " + t[0].ToString());

            var arg      = 51;
            var pVariant = Marshal.AllocCoTaskMem(16);

            Marshal.GetNativeVariantForObject(arg, pVariant);
            System.Runtime.InteropServices.ComTypes.DISPPARAMS par = new System.Runtime.InteropServices.ComTypes.DISPPARAMS()
            {
                cArgs             = 1,
                cNamedArgs        = 0,
                rgdispidNamedArgs = IntPtr.Zero,
                rgvarg            = pVariant
            };
            System.Runtime.InteropServices.ComTypes.INVOKEKIND flags = new System.Runtime.InteropServices.ComTypes.INVOKEKIND();
            IntPtr info     = new IntPtr();
            IntPtr puArgErr = new IntPtr();

            disp.Invoke(4, guid, 1, flags, par, out Res, info, puArgErr);
            disp.Invoke(1, guid, 1, flags, par, out Res, info, puArgErr);
            Console.WriteLine("Res = " + Res.ToString());

            var arg_6 = "";

            Marshal.GetNativeVariantForObject(arg_6, pVariant);
            System.Runtime.InteropServices.ComTypes.DISPPARAMS par_6 = new System.Runtime.InteropServices.ComTypes.DISPPARAMS()
            {
                cArgs             = 1,
                cNamedArgs        = 0,
                rgdispidNamedArgs = IntPtr.Zero,
                rgvarg            = pVariant
            };
            System.Runtime.InteropServices.ComTypes.INVOKEKIND flags_6 = new System.Runtime.InteropServices.ComTypes.INVOKEKIND();
            disp.Invoke(6, guid, 1, flags_6, par_6, out Res, info, puArgErr);


            Console.WriteLine("Res = " + Res.ToString());
            Console.ReadKey();
        }
Beispiel #13
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);
        }
Beispiel #14
0
        static void Main(string[] args)
        {
            // Получаем интерфейс IDispatch
            IDispatch disp = (IDispatch)(new Printer());

            // Получаем число интерфейсов информации типа
            int a = 0;

            disp.GetTypeInfoCount(out a);

            // Массив названий методов
            var namesMaethos = new string[] { "SpeedUp", "QualityUp", "GetMaxSpeed", "GetCurSpeed", "GetCurQuality",
                                              "SetPetName", "SetMaxSpeed", "GetPetName", "DisplayStats" };

            // Массив id методов
            int[] IDs = new int[namesMaethos.Length];

            // Пустой гуид
            Guid guid = new Guid();

            // Получаем массив соответсвующих ID
            disp.GetIDsOfNames(ref guid, namesMaethos, namesMaethos.Length, 1, IDs);

            // Коллекция: ключ - имя метода, значение - ID
            int i           = 0;
            var methodsDict = namesMaethos.ToDictionary(k => k, v => IDs[i++]);

            // Выведем полученные ID
            Console.WriteLine(string.Format("{0, -15} | {1}", "Method name", "ID"));
            foreach (var elem in methodsDict)
            {
                Console.WriteLine(string.Format("{0, -15} | {1}", elem.Key, elem.Value));
            }
            Console.WriteLine("--------------------------");

            // Для получения результата из Get функций
            object result;

            // Последние 2 параметра для Invoke
            var pExcepInfo = new IntPtr();
            var puArgErr   = new IntPtr();

            // 4-й параметр для Invoke
            INVOKEKIND wFlags = new INVOKEKIND();

            // Переменная для передачи аргументов в Set функции
            var pVariant = Marshal.AllocCoTaskMem(10);

            // Преобразуем строку в VARIANT
            Marshal.GetNativeVariantForObject("HP", pVariant);

            // Структура параметров
            DISPPARAMS param = new DISPPARAMS()
            {
                cArgs             = 1,
                cNamedArgs        = 0,
                rgdispidNamedArgs = IntPtr.Zero,
                rgvarg            = pVariant
            };

            // Привсваиваем имя
            disp.Invoke(methodsDict["SetPetName"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);

            Marshal.GetNativeVariantForObject(10, pVariant);
            param.rgvarg = pVariant;

            // Привсваиваем максимальную скорость
            disp.Invoke(methodsDict["SetMaxSpeed"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);

            // Получаем текущую скорость
            disp.Invoke(methodsDict["GetCurSpeed"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
            Console.WriteLine("Current speed: " + result.ToString());
            int curSpeed = Convert.ToInt32(result);

            // Получаем текущее качество
            disp.Invoke(methodsDict["GetCurQuality"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
            Console.WriteLine("Current quality: " + result.ToString());

            // Получаем максимальную скорость
            disp.Invoke(methodsDict["GetMaxSpeed"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
            int maxSpeed = Convert.ToInt32(result);

            Console.WriteLine("-------------------------");

            for (; curSpeed < maxSpeed; curSpeed++)
            {
                disp.Invoke(methodsDict["SpeedUp"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
                Console.WriteLine("SpeedUp! (+1)");
            }

            Console.WriteLine("-------------------------");

            // Получаем текущую скорость
            disp.Invoke(methodsDict["GetCurSpeed"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
            Console.WriteLine("Current speed: " + result.ToString());

            // Получаем текущее качество
            disp.Invoke(methodsDict["GetCurQuality"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);
            Console.WriteLine("Current quality: " + result.ToString());

            // Выводим информацию об объекте
            disp.Invoke(methodsDict["DisplayStats"], guid, 1, wFlags, param, out result, pExcepInfo, puArgErr);

            Console.ReadKey();
        }