public static void SetProperty(this IDispatchEx dispatchEx, string name, bool ignoreCase, object[] args) { if (args.Length < 1) { throw new ArgumentException("Invalid argument count", "args"); } int dispid; var result = dispatchEx.GetDispID(name, DispatchNameFlags.Ensure | (ignoreCase ? DispatchNameFlags.CaseInsensitive : DispatchNameFlags.CaseSensitive), out dispid); if (result == RawCOMHelpers.HResult.DISP_E_UNKNOWNNAME) { throw new NotSupportedException("Object does not support dynamic properties"); } Marshal.ThrowExceptionForHR(result); using (var argVariantArrayBlock = new CoTaskMemVariantArgsBlock(args)) { using (var namedArgDispidBlock = new CoTaskMemBlock(sizeof(int))) { EXCEPINFO excepInfo; Marshal.WriteInt32(namedArgDispidBlock.Addr, SpecialDispIDs.PropertyPut); var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 1, rgdispidNamedArgs = namedArgDispidBlock.Addr }; dispatchEx.InvokeEx(dispid, 0, DispatchFlags.PropertyPut | DispatchFlags.PropertyPutRef, ref dispArgs, IntPtr.Zero, out excepInfo); } } }
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 void Invoke( int dispId, ref Guid riid, int lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, out object result, IntPtr pExcepInfo, IntPtr puArgErr) { // Ignore riid // Ignore lcid // Ignore wFlags // Ignore pExcepInfo // Ignore puArgErr // Add strict check for parameters Here if (methodIDInfoDictionary.ContainsKey(dispId)) { try { MethodInfo mi = methodIDInfoDictionary[dispId]; int length = pDispParams.cArgs; Type interfaceType = mi.DeclaringType; Type classType = interfaceClassDictionary[interfaceType]; Console.WriteLine("Server ClassType: " + classType); Console.WriteLine("Server InterfaceType: " + interfaceType); object o = classInstanceDictionary[classType]; // Get the parameter array from the native array object[] args = Marshal.GetObjectsForNativeVariants(pDispParams.rgvarg, length); // Reverse the array Array.Reverse(args); result = mi.Invoke(o, args); } catch (Exception ex) { Console.WriteLine("Fail to invoke method for DispID " + dispId); Console.WriteLine(ex.ToString()); result = 1; } } else { Console.WriteLine("Method with DISPID " + dispId + " does not exist!"); throw new InvalidOperationException("Not supported method!"); } }
public static object Invoke(this IDispatchEx dispatchEx, object[] args, bool asConstructor) { using (var argVariantArrayBlock = new CoTaskMemVariantArgsByRefBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { EXCEPINFO excepInfo; var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; Marshal.ThrowExceptionForHR(dispatchEx.InvokeEx(SpecialDispIDs.Default, 0, asConstructor ? DispatchFlags.Construct : DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out excepInfo)); return(Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr)); } } }
// invoke a method on the target IDispatchEx object public static object Invoke(object target, string method, params object[] args) { var dispEx = target as IDispatchEx; if (dispEx == null) { throw new InvalidComObjectException(); } var dp = new System.Runtime.InteropServices.ComTypes.DISPPARAMS(); try { // repack arguments if (args.Length > 0) { // should be using stackalloc for DISPPARAMS arguments, but don't want enforce "/unsafe" int size = SIZE_OF_VARIANT * args.Length; dp.rgvarg = Marshal.AllocCoTaskMem(size); ZeroMemory(dp.rgvarg, size); // zero'ing is equal to VariantInit dp.cArgs = args.Length; for (int i = 0; i < dp.cArgs; i++) { Marshal.GetNativeVariantForObject(args[i], dp.rgvarg + SIZE_OF_VARIANT * (args.Length - i - 1)); } } int dispid; dispEx.GetDispID(method, fdexNameCaseSensitive, out dispid); var ei = new System.Runtime.InteropServices.ComTypes.EXCEPINFO(); var result = Type.Missing; dispEx.InvokeEx(dispid, 0, DISPATCH_METHOD, ref dp, ref result, ref ei, null); return(result); } finally { if (dp.rgvarg != IntPtr.Zero) { for (var i = 0; i < dp.cArgs; i++) { VariantClear(dp.rgvarg + SIZE_OF_VARIANT * i); } Marshal.FreeCoTaskMem(dp.rgvarg); } } }
public static object GetProperty(this IDispatchEx dispatchEx, string name, bool ignoreCase, object[] args) { int dispid; Marshal.ThrowExceptionForHR(dispatchEx.GetDispID(name, ignoreCase ? DispatchNameFlags.CaseInsensitive : DispatchNameFlags.CaseSensitive, out dispid)); using (var argVariantArrayBlock = new CoTaskMemVariantArgsBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { EXCEPINFO excepInfo; var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; Marshal.ThrowExceptionForHR(dispatchEx.InvokeEx(dispid, 0, DispatchFlags.PropertyGet, ref dispArgs, resultVariantBlock.Addr, out excepInfo)); return(Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr)); } } }
public static T Invoke <T>(object source, InvokeFlags invokeFlags, string name, params object[] args) { if (source == null) { throw new ArgumentNullException("source"); } if (!Enum.IsDefined(typeof(InvokeFlags), invokeFlags)) { throw new ArgumentOutOfRangeException("invokeFlags"); } if (args == null) { throw new ArgumentNullException("args"); } var memoryAllocationsToFree = new List <IntPtr>(); IntPtr rgdispidNamedArgs; int cNamedArgs; if (invokeFlags == InvokeFlags.DISPATCH_PROPERTYPUT) { // There must be at least one argument specified; only one if it is a non-indexed property and // multiple if there are index values as well as the value to set to if (args.Length < 1) { throw new ArgumentException("At least one argument must be specified for DISPATCH_PROPERTYPUT"); } var pdPutID = Marshal.AllocCoTaskMem(sizeof(Int64)); Marshal.WriteInt64(pdPutID, DISPID_PROPERTYPUT); memoryAllocationsToFree.Add(pdPutID); rgdispidNamedArgs = pdPutID; cNamedArgs = 1; } else { rgdispidNamedArgs = IntPtr.Zero; cNamedArgs = 0; } var variantsToClear = new List <IntPtr>(); IntPtr rgvarg; if (args.Length == 0) { rgvarg = IntPtr.Zero; } else { // We need to allocate enough memory to store a variant for each argument (and then populate this // memory) rgvarg = Marshal.AllocCoTaskMem(SizeOfNativeVariant * args.Length); memoryAllocationsToFree.Add(rgvarg); for (var index = 0; index < args.Length; index++) { // Note: The "IDispatch::Invoke method (Automation)" page // (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221479(v=vs.85).aspx) states that // "Arguments are stored in pDispParams->rgvarg in reverse order" so we'll reverse them here var arg = args[(args.Length - 1) - index]; // According to http://stackoverflow.com/a/1866268 it seems like using ToInt64 here will be valid // for both 32 and 64 bit machines. While this may apparently not be the most performant approach, // it should do the job. // Don't think we have to worry about pinning any references when we do this manipulation here // since we are allocating the array in unmanaged memory and so the garbage collector won't be // moving anything around (and GetNativeVariantForObject copies the reference and automatic // pinning will prevent the GC from interfering while this is happening). var pVariant = new IntPtr( rgvarg.ToInt64() + (SizeOfNativeVariant * index) ); Marshal.GetNativeVariantForObject(arg, pVariant); variantsToClear.Add(pVariant); } } var dispParams = new System.Runtime.InteropServices.ComTypes.DISPPARAMS() { cArgs = args.Length, rgvarg = rgvarg, cNamedArgs = cNamedArgs, rgdispidNamedArgs = rgdispidNamedArgs }; try { var dispId = GetDispId(source, name); var IID_NULL = new Guid("00000000-0000-0000-0000-000000000000"); UInt32 pArgErr = 0; object varResult; var excepInfo = new System.Runtime.InteropServices.ComTypes.EXCEPINFO(); var hrRet = ((IDispatch)source).Invoke ( dispId, ref IID_NULL, LOCALE_SYSTEM_DEFAULT, (ushort)invokeFlags, ref dispParams, out varResult, ref excepInfo, out pArgErr ); if (hrRet != 0) { var message = "Failing attempting to invoke method with DispId " + dispId + ": "; if ((excepInfo.bstrDescription ?? "").Trim() == "") { message += "Unspecified error"; } else { message += excepInfo.bstrDescription; } var errorType = GetErrorMessageForHResult(hrRet); if (errorType != CommonErrors.Unknown) { message += " [" + errorType.ToString() + "]"; } throw new ArgumentException(message); } return((T)varResult); } finally { foreach (var variantToClear in variantsToClear) { VariantClear(variantToClear); } foreach (var memoryAllocationToFree in memoryAllocationsToFree) { Marshal.FreeCoTaskMem(memoryAllocationToFree); } } }
public static object Invoke(this IDispatchEx dispatchEx, object[] args) { using (var argVariantArrayBlock = new CoTaskMemVariantArgsByRefBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { EXCEPINFO excepInfo; var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; dispatchEx.InvokeEx(SpecialDispIDs.Default, 0, DispatchFlags.Method, ref dispArgs, resultVariantBlock.Addr, out excepInfo); return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr); } } }
public static object GetProperty(this IDispatchEx dispatchEx, string name, bool ignoreCase, object[] args) { int dispid; Marshal.ThrowExceptionForHR(dispatchEx.GetDispID(name, ignoreCase ? DispatchNameFlags.CaseInsensitive : DispatchNameFlags.CaseSensitive, out dispid)); using (var argVariantArrayBlock = new CoTaskMemVariantArgsBlock(args)) { using (var resultVariantBlock = new CoTaskMemVariantBlock()) { EXCEPINFO excepInfo; var dispArgs = new DISPPARAMS { cArgs = args.Length, rgvarg = argVariantArrayBlock.Addr, cNamedArgs = 0, rgdispidNamedArgs = IntPtr.Zero }; dispatchEx.InvokeEx(dispid, 0, DispatchFlags.PropertyGet, ref dispArgs, resultVariantBlock.Addr, out excepInfo); return Marshal.GetObjectForNativeVariant(resultVariantBlock.Addr); } } }