public static void SetProperty(this IDispatch dispatch, string name, params object[] args) { if (args.Length < 1) { throw new ArgumentException("Invalid argument count", nameof(args)); } var dispid = dispatch.GetDispIDForName(name); using (var argVariantArrayBlock = new CoTaskMemVariantArgsBlock(args)) { using (var namedArgDispidBlock = new CoTaskMemBlock(sizeof(int))) { Marshal.WriteInt32(namedArgDispidBlock.Addr, SpecialDispIDs.PropertyPut); var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 1, rgdispidNamedArgs = namedArgDispidBlock.Addr }; var result = dispatch.Invoke(dispid, ref iid, 0, DispatchFlags.PropertyPut | DispatchFlags.PropertyPutRef, ref dispArgs, IntPtr.Zero, out _, out _); if (result == HResult.DISP_E_MEMBERNOTFOUND) { // VBScript objects can be finicky about property-put dispatch flags result = dispatch.Invoke(dispid, iid, 0, DispatchFlags.PropertyPut, ref dispArgs, IntPtr.Zero, out _, out _); if (result == HResult.DISP_E_MEMBERNOTFOUND) { result = dispatch.Invoke(dispid, iid, 0, DispatchFlags.PropertyPutRef, ref dispArgs, IntPtr.Zero, out _, out _); } } HResult.Check(result); } } }
public unsafe void IDispatch_Invoke_Invoke_Success() { using var image = new Bitmap(16, 32); IPictureDisp picture = MockAxHost.GetIPictureDispFromPicture(image); IDispatch dispatch = (IDispatch)picture; Guid riid = Guid.Empty; var dispParams = new DISPPARAMS(); var varResult = new object[1]; var excepInfo = new EXCEPINFO(); uint argErr = 0; HRESULT hr = dispatch.Invoke( (DispatchID)4, &riid, Kernel32.GetThreadLocale(), DISPATCH.PROPERTYGET, &dispParams, varResult, &excepInfo, &argErr ); Assert.Equal(HRESULT.S_OK, hr); Assert.Equal(16, GdiHelper.HimetricToPixelY((int)varResult[0])); Assert.Equal(0u, argErr); }
public static int InvokePropertySet(this IDispatch dispatch, int dispid, object value) { int hr = NativeMethods.S_OK; var guid = Guid.Empty; var lcid = NativeMethods.LOCALE_SYSTEM_DEFAULT; var flags = System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT; var pExcepInfo = default(System.Runtime.InteropServices.ComTypes.EXCEPINFO); uint pArgErr = 0; Variant pVarResult = default(Variant); VariantArgPtr va = new VariantArgPtr(1); var dp = new System.Runtime.InteropServices.ComTypes.DISPPARAMS() { cArgs = va.Count, rgvarg = va, cNamedArgs = 1, rgdispidNamedArgs = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int))) }; Marshal.WriteInt32(dp.rgdispidNamedArgs, (int)NativeMethods.DISPID_PROPERTYPUT); if (value is VariantWrapper) { Variant variant = new Variant((VariantWrapper)value); Marshal.StructureToPtr(variant, va[0], false); } else { Marshal.GetNativeVariantForObject(value, va[0]); } try { hr = dispatch.Invoke( dispid, ref guid, lcid, flags, ref dp, out pVarResult, ref pExcepInfo, out pArgErr ); } catch { GlobalExceptionHandler.HandleException(); } finally { Marshal.FreeCoTaskMem(dp.rgdispidNamedArgs); va.Dispose(); } return(hr); }
public object Invoke(bool asConstructor, params object[] args) { if (asConstructor) { throw new NotSupportedException("The object does not support constructor invocation"); } return(dispatch.Invoke(args)); }
private static object DynamicInvoke(IDispatch dispatch, int dispID, object[] parameters, ComTypes.INVOKEKIND invokeKind) { Array.Reverse(parameters); IntPtr paramsPtr = Marshal.AllocCoTaskMem(parameters.Length * SizeOfVariant); ComTypes.DISPPARAMS[] dispParams = new ComTypes.DISPPARAMS[1]; if (IsSet(invokeKind)) { dispParams[0].cNamedArgs = 1; dispParams[0].rgdispidNamedArgs = Marshal.AllocCoTaskMem(SizeOfVariant); Marshal.Copy(new int[] { DISPID_PROPERTYPUT }, 0, dispParams[0].rgdispidNamedArgs, 1); } else { dispParams[0].cNamedArgs = 0; dispParams[0].rgdispidNamedArgs = IntPtr.Zero; } dispParams[0].cArgs = parameters.Length; dispParams[0].rgvarg = paramsPtr; try { int ptr = paramsPtr.ToInt32(); foreach (object parameter in parameters) { Marshal.GetNativeVariantForObject(parameter, new IntPtr(ptr)); ptr += SizeOfVariant; } Guid guid = Guid.Empty; object[] result = new object[] { null }; Marshal.ThrowExceptionForHR(dispatch.Invoke( dispID, ref guid, CultureInfo.CurrentCulture.LCID, (short)invokeKind, dispParams, result, null, null)); return(result[0]); } finally { if (dispParams[0].rgdispidNamedArgs != IntPtr.Zero) { Marshal.FreeCoTaskMem(dispParams[0].rgdispidNamedArgs); dispParams[0].rgdispidNamedArgs = IntPtr.Zero; } if (dispParams[0].rgvarg != IntPtr.Zero) { Marshal.FreeCoTaskMem(dispParams[0].rgvarg); dispParams[0].rgvarg = IntPtr.Zero; } paramsPtr = IntPtr.Zero; } }
public static object InvokeScript(IHTMLDocument doc, string scriptName, object[] args) { object result = null; NativeMethods.tagDISPPARAMS tagDISPPARAMS = new NativeMethods.tagDISPPARAMS(); tagDISPPARAMS.rgvarg = IntPtr.Zero; try { IDispatch dispatch = doc.Script as IDispatch; if (dispatch != null) { Guid empty = Guid.Empty; string[] rgszNames = new string[] { scriptName }; int[] array = new int[] { -1 }; int iDsOfNames = dispatch.GetIDsOfNames(ref empty, rgszNames, 1, SafeNativeMethods.GetThreadLCID(), array); if (SafeNativeMethods.Succeeded(iDsOfNames) && array[0] != -1) { if (args != null) { Array.Reverse(args); } tagDISPPARAMS.rgvarg = ((args == null) ? IntPtr.Zero : SafeNativeMethods.ArrayToVARIANTVector(args)); tagDISPPARAMS.cArgs = ((args == null) ? 0 : args.Length); tagDISPPARAMS.rgdispidNamedArgs = IntPtr.Zero; tagDISPPARAMS.cNamedArgs = 0; object[] array2 = new object[1]; if (dispatch.Invoke(array[0], ref empty, SafeNativeMethods.GetThreadLCID(), 1, tagDISPPARAMS, array2, new NativeMethods.tagEXCEPINFO(), null) == 0) { result = array2[0]; } } } } catch (Exception ex) { if (ClientUtils.IsSecurityOrCriticalException(ex)) { throw; } } finally { if (tagDISPPARAMS.rgvarg != IntPtr.Zero) { SafeNativeMethods.FreeVARIANTVector(tagDISPPARAMS.rgvarg, args.Length); } } return(result); }
private bool ReflectUserMode() { Guid id = Guid.Empty; var prm = new DISPPARAMS(); uint lcid = 0; ushort wFlags = 2; dynamic result; var ei = new EXCEPINFO(); _site.Invoke(ActiveXConstants.DISPID_AMBIENT_USERMODE, ref id, lcid, wFlags, ref prm, out result, ref ei, null); return(result); }
public static object Invoke(this IDispatch dispatch, params object[] args) { using (var argVariantArrayBlock = new CoTaskMemVariantArgsByRefBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; HResult.Check(dispatch.Invoke(SpecialDispIDs.Default, ref iid, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _, out _)); return(Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr)); } } }
public static string GetValue(object comObj, string name) { 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); } try { int language_id = 0; int DISPATCH_METHOD = 0x1; int DISPATCH_PROPERTYGET = 0x2; int[] displayIDs = new int[1]; Guid empty = Guid.Empty; string[] names = new string[] { name }; dispatch.GetIDsOfNames(ref empty, names, names.Length, language_id, displayIDs); System.Runtime.InteropServices.ComTypes.DISPPARAMS dspp = new System.Runtime.InteropServices.ComTypes.DISPPARAMS(); System.Runtime.InteropServices.ComTypes.EXCEPINFO ei = new System.Runtime.InteropServices.ComTypes.EXCEPINFO(); IntPtr[] arg_err = new IntPtr[10]; object result; if (1 == displayIDs.Length) { dispatch.Invoke(displayIDs[0], ref empty, language_id, (ushort)(DISPATCH_METHOD | DISPATCH_PROPERTYGET), ref dspp, out result, ref ei, arg_err); return(result.ToString()); } return(String.Empty); } catch (Exception e) { Console.WriteLine(e.Message); return(String.Empty); } }
static object InvokePropertyGetter(IDispatch target, int dispId) { var paramArray = new ComTypes.DISPPARAMS[1]; paramArray[0].cArgs = 0; paramArray[0].cNamedArgs = 0; ComTypes.EXCEPINFO info = default(ComTypes.EXCEPINFO); object result = null; uint puArgErrNotUsed = 0; target.Invoke(dispId, new Guid(), 0x0409, ComTypes.INVOKEKIND.INVOKE_PROPERTYGET, paramArray, out result, out info, out puArgErrNotUsed); return(result); }
public static object PropertyGet_NoArgs(IDispatch obj, int memberId) { var pDispParams = new ComTypes.DISPPARAMS(); var pExcepInfo = new ComTypes.EXCEPINFO(); Guid guid = new Guid(); int hr = obj.Invoke(memberId, ref guid, 0, (uint)(InvokeKind.DISPATCH_METHOD | InvokeKind.DISPATCH_PROPERTYGET), ref pDispParams, out var pVarResult, ref pExcepInfo, out uint ErrArg); if (hr < 0) { // could expand this to better handle DISP_E_EXCEPTION throw Marshal.GetExceptionForHR(hr); } return(pVarResult); }
public static object GetProperty(this IDispatch dispatch, string name, params object[] args) { if (!MiscHelpers.Try(out int dispid, () => dispatch.GetDispIDForName(name))) { return(Nonexistent.Value); } using (var argVariantArrayBlock = new CoTaskMemVariantArgsBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; HResult.Check(dispatch.Invoke(dispid, ref iid, 0, DispatchFlags.PropertyGet, ref dispArgs, resultVariantBlock.Addr, out _, out _)); return(Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr)); } } }
public static object InvokeMethod(this IDispatch dispatch, string name, params object[] args) { var dispid = dispatch.GetDispIDForName(name); if (dispid == SpecialDispIDs.GetEnumerator) { return(dispatch.GetProperty(SpecialMemberNames.NewEnum, args)); } using (var argVariantArrayBlock = new CoTaskMemVariantArgsByRefBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; HResult.Check(dispatch.Invoke(dispid, iid, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out _, out _)); return(Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr)); } } }
/// <summary> /// A basic helper for IDispatch::Invoke /// </summary> /// <param name="obj">The IDispatch object of which you want to invoke a member on</param> /// <param name="memberId">The dispatch ID of the member to invoke</param> /// <param name="invokeKind">See InvokeKind enumeration</param> /// <param name="args">Array of arguments to pass to the call, or null for no args</param> /// <remarks>TODO support DISPATCH_PROPERTYPUTREF (property-set) which requires special handling</remarks> /// <returns>An object representing the return value from the called routine</returns> public static object Invoke(IDispatch obj, int memberId, InvokeKind invokeKind, object[] args = null) { var pDispParams = PrepareDispatchArgs(args); var pExcepInfo = new ComTypes.EXCEPINFO(); var hr = obj.Invoke(memberId, ref _guid_null, 0, (uint)invokeKind, ref pDispParams, out var pVarResult, ref pExcepInfo, out var pErrArg); UnprepareDispatchArgs(pDispParams); if (ComHelper.HRESULT_FAILED(hr)) { if ((hr == (int)KnownComHResults.DISP_E_EXCEPTION) && (ComHelper.HRESULT_FAILED(pExcepInfo.scode))) { throw RdMarshal.GetExceptionForHR(pExcepInfo.scode); } throw RdMarshal.GetExceptionForHR(hr); } return(pVarResult); }
public unsafe void IDispatch_Invoke_Invoke_Success() { using var image = new Bitmap(16, 32); IPictureDisp picture = SubAxHost.GetIPictureDispFromPicture(image); IDispatch dispatch = (IDispatch)picture; Guid riid = Guid.Empty; var dispParams = new DISPPARAMS(); var varResult = new object[1]; var excepInfo = new EXCEPINFO(); uint argErr = 0; HRESULT hr = dispatch.Invoke( (DispatchID)4, &riid, 0, DISPATCH.PROPERTYGET, &dispParams, varResult, &excepInfo, &argErr ); }
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(); }
public static int InvokePropertyGet(this IDispatch dispatch, int dispid, out object value) { int hr = NativeMethods.S_OK; value = null; var guid = Guid.Empty; var lcid = NativeMethods.LOCALE_SYSTEM_DEFAULT; var flags = System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_PROPERTYGET; var dp = default(System.Runtime.InteropServices.ComTypes.DISPPARAMS); var pExcepInfo = default(System.Runtime.InteropServices.ComTypes.EXCEPINFO); uint pArgErr = 0; Variant variant = default(Variant); try { hr = dispatch.Invoke( dispid, ref guid, lcid, flags, ref dp, out variant, ref pExcepInfo, out pArgErr ); if (MarshalEx.Succeeded(hr)) { try { switch (variant.VariantType) { case VarEnum.VT_PTR: GlobalExceptionHandler.HandleException(); break; case VarEnum.VT_UNKNOWN: case VarEnum.VT_DISPATCH: if (variant.ptr1.Equals(IntPtr.Zero) == false) { value = new ComPtr(variant.ptr1); int count = Marshal.Release(variant.ptr1); } break; case VarEnum.VT_USERDEFINED: value = variant.ToObject(); break; default: value = variant.ToObject(); break; } } catch (COMException ex) { hr = ex.ErrorCode; } } } catch { GlobalExceptionHandler.HandleException(); } finally { variant.Clear(); } return(hr); }
public static int InvokeMethod(this IDispatch dispatch, int dispId, object[] args, out object returnValue) { int hr = NativeMethods.S_OK; var riid = new Guid(NativeMethods.IID_NULL); VariantArgPtr va = new VariantArgPtr(args.Length); returnValue = null; var dp = new System.Runtime.InteropServices.ComTypes.DISPPARAMS() { cArgs = args.Length, rgvarg = va, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; Array.Reverse(args); for (int i = 0; i < args.Length; i++) { var arg = args[i]; if (arg is VariantWrapper) { Variant variant = new Variant((VariantWrapper)arg); Marshal.StructureToPtr(variant, va[i], false); } else { Marshal.GetNativeVariantForObject(arg, va[i]); } } try { Variant pVarResult = default(Variant); var pExcepInfo = default(System.Runtime.InteropServices.ComTypes.EXCEPINFO); uint pArgErr = 0; hr = dispatch.Invoke ( dispId, ref riid, NativeMethods.LOCALE_SYSTEM_DEFAULT, System.Runtime.InteropServices.ComTypes.INVOKEKIND.INVOKE_FUNC, ref dp, out pVarResult, ref pExcepInfo, out pArgErr ); if (hr == 0) { for (var i = 0; i < args.Length; i++) { var arg = args[i]; if (arg is VariantWrapper) { Variant variant = (Variant)Marshal.PtrToStructure(va[i], typeof(Variant)); try { switch (variant.VariantType) { case VarEnum.VT_UNKNOWN: case VarEnum.VT_DISPATCH: args[i] = new ComPtr(variant.ptr1); if (((ComPtr)returnValue).IsInvalid == false) { Marshal.Release(variant.ptr1); } break; default: args[i] = variant.ToObject(); break; } } catch (COMException ex) { hr = ex.ErrorCode; } //VarEnum variantType = variant.VariantType & (VarEnum.VT_NULL | VarEnum.VT_I2 | VarEnum.VT_I4 | VarEnum.VT_R4 | VarEnum.VT_R8 | VarEnum.VT_CY | VarEnum.VT_DATE | VarEnum.VT_BSTR | VarEnum.VT_DISPATCH | VarEnum.VT_ERROR | VarEnum.VT_BOOL | VarEnum.VT_VARIANT | VarEnum.VT_UNKNOWN | VarEnum.VT_DECIMAL | VarEnum.VT_I1 | VarEnum.VT_UI1 | VarEnum.VT_UI2 | VarEnum.VT_UI4 | VarEnum.VT_I8 | VarEnum.VT_UI8 | VarEnum.VT_INT | VarEnum.VT_UINT | VarEnum.VT_VOID | VarEnum.VT_HRESULT | VarEnum.VT_PTR | VarEnum.VT_SAFEARRAY | VarEnum.VT_CARRAY | VarEnum.VT_USERDEFINED | VarEnum.VT_LPSTR | VarEnum.VT_LPWSTR | VarEnum.VT_RECORD | VarEnum.VT_FILETIME | VarEnum.VT_BLOB | VarEnum.VT_STREAM | VarEnum.VT_STORAGE | VarEnum.VT_STREAMED_OBJECT | VarEnum.VT_STORED_OBJECT | VarEnum.VT_BLOB_OBJECT | VarEnum.VT_CF | VarEnum.VT_CLSID | VarEnum.VT_VECTOR | VarEnum.VT_ARRAY); //args[i] = variant.ToObject(); //args[i] = Marshal.GetObjectForNativeVariant(variant.variant_part.variant_union._dispatch); //NativeMethods.VariantClear(variant.variant_part.variant_union.pointer_data); } } switch (pVarResult.VariantType) { case VarEnum.VT_UNKNOWN: case VarEnum.VT_DISPATCH: returnValue = new ComPtr(pVarResult.ptr1); if (((ComPtr)returnValue).IsInvalid == false) { Marshal.Release(pVarResult.ptr1); } break; case VarEnum.VT_EMPTY: break; default: returnValue = pVarResult.ToObject(); break; } } else { for (var i = 0; i < args.Length; i++) { if (args[i] is VariantWrapper) { args[i] = null; } } } Array.Reverse(args); } catch { GlobalExceptionHandler.HandleException(); } finally { va.Dispose(); } return(hr); }
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(); }
/// <summary> /// Invoke the COM member /// </summary> /// <param name="target">IDispatch object</param> /// <param name="dispId">Dispatch identifier that identifies the member</param> /// <param name="args">Arguments passed in</param> /// <param name="byRef">Boolean array that indicates by-Ref parameters</param> /// <param name="invokeKind">Invocation kind</param> /// <returns></returns> internal static object Invoke(IDispatch target, int dispId, object[] args, bool[] byRef, COM.INVOKEKIND invokeKind) { Diagnostics.Assert(target != null, "Caller makes sure an IDispatch object passed in."); Diagnostics.Assert(args == null || byRef == null || args.Length == byRef.Length, "If 'args' and 'byRef' are not null, then they should be one-on-one mapping."); int argCount = args != null ? args.Length : 0; int refCount = byRef != null ? byRef.Count(c => c) : 0; IntPtr variantArgArray = IntPtr.Zero, dispIdArray = IntPtr.Zero, tmpVariants = IntPtr.Zero; try { // Package arguments if (argCount > 0) { variantArgArray = NewVariantArray(argCount); int refIndex = 0; for (int i = 0; i < argCount; i++) { // !! The arguments should be in REVERSED order!! int actualIndex = argCount - i - 1; IntPtr varArgPtr = variantArgArray + s_variantSize * actualIndex; // If need to pass by ref, create a by-ref variant if (byRef != null && byRef[i]) { // Allocate memory for temporary VARIANTs used in by-ref marshalling if (tmpVariants == IntPtr.Zero) { tmpVariants = NewVariantArray(refCount); } // Create a VARIANT that the by-ref VARIANT points to IntPtr tmpVarPtr = tmpVariants + s_variantSize * refIndex; Marshal.GetNativeVariantForObject(args[i], tmpVarPtr); // Create the by-ref VARIANT MakeByRefVariant(tmpVarPtr, varArgPtr); refIndex++; } else { Marshal.GetNativeVariantForObject(args[i], varArgPtr); } } } var paramArray = new COM.DISPPARAMS[1]; paramArray[0].rgvarg = variantArgArray; paramArray[0].cArgs = argCount; if (invokeKind == COM.INVOKEKIND.INVOKE_PROPERTYPUT || invokeKind == COM.INVOKEKIND.INVOKE_PROPERTYPUTREF) { // For property putters, the first DISPID argument needs to be DISPID_PROPERTYPUT dispIdArray = Marshal.AllocCoTaskMem(4); // Allocate 4 bytes to hold a 32-bit signed integer Marshal.WriteInt32(dispIdArray, DISPID_PROPERTYPUT); paramArray[0].cNamedArgs = 1; paramArray[0].rgdispidNamedArgs = dispIdArray; } else { // Otherwise, no named parameters are necessary since powershell parser doesn't support named parameter paramArray[0].cNamedArgs = 0; paramArray[0].rgdispidNamedArgs = IntPtr.Zero; } // Make the call EXCEPINFO info = default(EXCEPINFO); object result = null; try { // 'puArgErr' is set when IDispatch.Invoke fails with error code 'DISP_E_PARAMNOTFOUND' and 'DISP_E_TYPEMISMATCH'. // Appropriate exceptions will be thrown in such cases, but FullCLR doesn't use 'puArgErr' in the exception handling, so we also ignore it. uint puArgErrNotUsed = 0; target.Invoke(dispId, s_IID_NULL, LCID_DEFAULT, invokeKind, paramArray, out result, out info, out puArgErrNotUsed); } catch (Exception innerException) { // When 'IDispatch.Invoke' returns error code, CLR will raise exception based on internal HR-to-Exception mapping. // Description of the return code can be found at https://msdn.microsoft.com/en-us/library/windows/desktop/ms221479(v=vs.85).aspx // According to CoreCLR team (yzha), the exception needs to be wrapped as an inner exception of TargetInvocationException. string exceptionMsg = null; if (innerException.HResult == DISP_E_EXCEPTION) { // Invoke was successful but the actual underlying method failed. // In this case, we use EXCEPINFO to get additional error info. // Use EXCEPINFO.scode or EXCEPINFO.wCode as HR to construct the correct exception. int code = info.scode != 0 ? info.scode : info.wCode; innerException = Marshal.GetExceptionForHR(code, IntPtr.Zero) ?? innerException; // Get the richer error description if it's available. if (info.bstrDescription != IntPtr.Zero) { exceptionMsg = Marshal.PtrToStringBSTR(info.bstrDescription); Marshal.FreeBSTR(info.bstrDescription); } // Free the BSTRs if (info.bstrSource != IntPtr.Zero) { Marshal.FreeBSTR(info.bstrSource); } if (info.bstrHelpFile != IntPtr.Zero) { Marshal.FreeBSTR(info.bstrHelpFile); } } var outerException = exceptionMsg == null ? new TargetInvocationException(innerException) : new TargetInvocationException(exceptionMsg, innerException); throw outerException; } // Now back propagate the by-ref arguments if (refCount > 0) { for (int i = 0; i < argCount; i++) { // !! The arguments should be in REVERSED order!! int actualIndex = argCount - i - 1; // If need to pass by ref, back propagate if (byRef != null && byRef[i]) { args[i] = Marshal.GetObjectForNativeVariant(variantArgArray + s_variantSize * actualIndex); } } } return result; } finally { // Free the variant argument array if (variantArgArray != IntPtr.Zero) { for (int i = 0; i < argCount; i++) { VariantClear(variantArgArray + s_variantSize * i); } Marshal.FreeCoTaskMem(variantArgArray); } // Free the dispId array if (dispIdArray != IntPtr.Zero) { Marshal.FreeCoTaskMem(dispIdArray); } // Free the temporary variants created when handling by-Ref arguments if (tmpVariants != IntPtr.Zero) { for (int i = 0; i < refCount; i++) { VariantClear(tmpVariants + s_variantSize * i); } Marshal.FreeCoTaskMem(tmpVariants); } } }
private string GetName(IDispatch dispatch) { string theName = null; if (nameProperty != null) { IntPtr ptrDispatch = Marshal.GetIDispatchForObject(dispatch); try { if (ptrDispatch != IntPtr.Zero) { object typedObject = Marshal.GetTypedObjectForIUnknown(ptrDispatch, comType); if (typedObject != null) { theName = (string)nameProperty.GetValue(typedObject, null); } } } catch { theName = null; } finally { if (ptrDispatch != IntPtr.Zero) { Marshal.Release(ptrDispatch); ptrDispatch = IntPtr.Zero; } } } if (theName == null) { Guid guid = Guid.Empty; string[] names = new string[] { "Name" }; int[] dispIds = new int[] { 0 }; dispatch.GetIDsOfNames(ref guid, names, names.Length, 0, dispIds); if (dispIds[0] != -1) { ComTypes.DISPPARAMS[] dispParams = new ComTypes.DISPPARAMS[1]; dispParams[0].cNamedArgs = 0; dispParams[0].rgdispidNamedArgs = IntPtr.Zero; dispParams[0].cArgs = 1; dispParams[0].rgvarg = Marshal.AllocCoTaskMem(0x1000); try { Marshal.GetNativeVariantForObject(theName, dispParams[0].rgvarg); dispatch.Invoke( dispIds[0], ref guid, CultureInfo.CurrentCulture.LCID, (short)ComTypes.INVOKEKIND.INVOKE_PROPERTYGET, dispParams, null, null, null); object retValue = Marshal.GetObjectForNativeVariant(dispParams[0].rgvarg); if (retValue is string) { theName = (string)retValue; } } finally { Marshal.FreeCoTaskMem(dispParams[0].rgvarg); dispParams[0].rgvarg = IntPtr.Zero; } } } return(theName); }
/// <summary> /// Invoke the COM member /// </summary> /// <param name="target">IDispatch object</param> /// <param name="dispId">Dispatch identifier that identifies the member</param> /// <param name="args">Arguments passed in</param> /// <param name="byRef">Boolean array that indicates by-Ref parameters</param> /// <param name="invokeKind">Invocation kind</param> /// <returns></returns> internal static object Invoke(IDispatch target, int dispId, object[] args, bool[] byRef, COM.INVOKEKIND invokeKind) { Diagnostics.Assert(target != null, "Caller makes sure an IDispatch object passed in."); Diagnostics.Assert(args == null || byRef == null || args.Length == byRef.Length, "If 'args' and 'byRef' are not null, then they should be one-on-one mapping."); int argCount = args != null ? args.Length : 0; int refCount = byRef != null?byRef.Count(c => c) : 0; IntPtr variantArgArray = IntPtr.Zero, dispIdArray = IntPtr.Zero, tmpVariants = IntPtr.Zero; try { // Package arguments if (argCount > 0) { variantArgArray = NewVariantArray(argCount); int refIndex = 0; for (int i = 0; i < argCount; i++) { // !! The arguments should be in REVERSED order!! int actualIndex = argCount - i - 1; IntPtr varArgPtr = variantArgArray + s_variantSize * actualIndex; // If need to pass by ref, create a by-ref variant if (byRef != null && byRef[i]) { // Allocate memory for temporary VARIANTs used in by-ref marshalling if (tmpVariants == IntPtr.Zero) { tmpVariants = NewVariantArray(refCount); } // Create a VARIANT that the by-ref VARIANT points to IntPtr tmpVarPtr = tmpVariants + s_variantSize * refIndex; Marshal.GetNativeVariantForObject(args[i], tmpVarPtr); // Create the by-ref VARIANT MakeByRefVariant(tmpVarPtr, varArgPtr); refIndex++; } else { Marshal.GetNativeVariantForObject(args[i], varArgPtr); } } } var paramArray = new COM.DISPPARAMS[1]; paramArray[0].rgvarg = variantArgArray; paramArray[0].cArgs = argCount; if (invokeKind == COM.INVOKEKIND.INVOKE_PROPERTYPUT || invokeKind == COM.INVOKEKIND.INVOKE_PROPERTYPUTREF) { // For property putters, the first DISPID argument needs to be DISPID_PROPERTYPUT dispIdArray = Marshal.AllocCoTaskMem(4); // Allocate 4 bytes to hold a 32-bit signed integer Marshal.WriteInt32(dispIdArray, DISPID_PROPERTYPUT); paramArray[0].cNamedArgs = 1; paramArray[0].rgdispidNamedArgs = dispIdArray; } else { // Otherwise, no named parameters are necessary since powershell parser doesn't support named parameter paramArray[0].cNamedArgs = 0; paramArray[0].rgdispidNamedArgs = IntPtr.Zero; } // Make the call EXCEPINFO info = default(EXCEPINFO); object result = null; try { // 'puArgErr' is set when IDispatch.Invoke fails with error code 'DISP_E_PARAMNOTFOUND' and 'DISP_E_TYPEMISMATCH'. // Appropriate exceptions will be thrown in such cases, but FullCLR doesn't use 'puArgErr' in the exception handling, so we also ignore it. uint puArgErrNotUsed = 0; target.Invoke(dispId, s_IID_NULL, LCID_DEFAULT, invokeKind, paramArray, out result, out info, out puArgErrNotUsed); } catch (Exception innerException) { // When 'IDispatch.Invoke' returns error code, CLR will raise exception based on internal HR-to-Exception mapping. // Description of the return code can be found at https://msdn.microsoft.com/library/windows/desktop/ms221479(v=vs.85).aspx // According to CoreCLR team (yzha), the exception needs to be wrapped as an inner exception of TargetInvocationException. string exceptionMsg = null; if (innerException.HResult == DISP_E_EXCEPTION) { // Invoke was successful but the actual underlying method failed. // In this case, we use EXCEPINFO to get additional error info. // Use EXCEPINFO.scode or EXCEPINFO.wCode as HR to construct the correct exception. int code = info.scode != 0 ? info.scode : info.wCode; innerException = Marshal.GetExceptionForHR(code, IntPtr.Zero) ?? innerException; // Get the richer error description if it's available. if (info.bstrDescription != IntPtr.Zero) { exceptionMsg = Marshal.PtrToStringBSTR(info.bstrDescription); Marshal.FreeBSTR(info.bstrDescription); } // Free the BSTRs if (info.bstrSource != IntPtr.Zero) { Marshal.FreeBSTR(info.bstrSource); } if (info.bstrHelpFile != IntPtr.Zero) { Marshal.FreeBSTR(info.bstrHelpFile); } } var outerException = exceptionMsg == null ? new TargetInvocationException(innerException) : new TargetInvocationException(exceptionMsg, innerException); throw outerException; } // Now back propagate the by-ref arguments if (refCount > 0) { for (int i = 0; i < argCount; i++) { // !! The arguments should be in REVERSED order!! int actualIndex = argCount - i - 1; // If need to pass by ref, back propagate if (byRef != null && byRef[i]) { args[i] = Marshal.GetObjectForNativeVariant(variantArgArray + s_variantSize * actualIndex); } } } return(result); } finally { // Free the variant argument array if (variantArgArray != IntPtr.Zero) { for (int i = 0; i < argCount; i++) { VariantClear(variantArgArray + s_variantSize * i); } Marshal.FreeCoTaskMem(variantArgArray); } // Free the dispId array if (dispIdArray != IntPtr.Zero) { Marshal.FreeCoTaskMem(dispIdArray); } // Free the temporary variants created when handling by-Ref arguments if (tmpVariants != IntPtr.Zero) { for (int i = 0; i < refCount; i++) { VariantClear(tmpVariants + s_variantSize * i); } Marshal.FreeCoTaskMem(tmpVariants); } } }
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(); }