/// <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); }
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); }
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); }
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()); } }
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); }
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); }
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(); }
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); }
/// <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); } }
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); }
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(); }
// 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); }
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(); }