Beispiel #1
0
        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);
        }
Beispiel #3
0
        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));
         }
     }
 }
Beispiel #5
0
    // 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));
                }
            }
        }
Beispiel #7
0
        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);
                }
            }
        }
        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);
                }
            }
        }