예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        public object Invoke(bool asConstructor, params object[] args)
        {
            if (asConstructor)
            {
                throw new NotSupportedException("The object does not support constructor invocation");
            }

            return(dispatch.Invoke(args));
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
파일: WebBrowser2.cs 프로젝트: qwdingyu/C-
        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);
        }
예제 #8
0
 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));
         }
     }
 }
예제 #9
0
    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);
        }
    }
예제 #10
0
        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);
        }
예제 #12
0
        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));
                }
            }
        }
예제 #13
0
        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));
                }
            }
        }
예제 #14
0
        /// <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);
        }
예제 #15
0
        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
                );
        }
예제 #16
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();
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
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();
        }
예제 #20
0
        /// <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);
                }
            }
        }
예제 #21
0
        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);
        }
예제 #22
0
        /// <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);
                }
            }
        }
예제 #23
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();
        }