Example #1
0
        object IReflect.InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
        {
            object ret = null;
            // Check direct IDispatch call using a dispid (see http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx)
            const string dispidToken = "[DISPID=";

            if (name.StartsWith(dispidToken))
            {
                int dispid = int.Parse(name.Substring(dispidToken.Length, name.Length - dispidToken.Length - 1));
                if (_dispidCache == null)
                {
                    // WebBrowser has many properties, so we build a dispid cache on it
                    _dispidCache = new Dictionary <int, PropertyInfo>();
                    foreach (PropertyInfo pi in _host.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
                    {
                        if ((!pi.CanRead) || (pi.GetIndexParameters().Length > 0))
                        {
                            continue;
                        }
                        object[] atts = pi.GetCustomAttributes(typeof(DispIdAttribute), true);
                        if ((atts != null) && (atts.Length > 0))
                        {
                            DispIdAttribute da = (DispIdAttribute)atts[0];
                            _dispidCache[da.Value] = pi;
                        }
                    }
                }
                PropertyInfo property;
                if (_dispidCache.TryGetValue(dispid, out property))
                {
                    ret = property.GetValue(_host, null);
                }
            }
            return(ret);
        }
Example #2
0
        public void TestITwsEventsDispIdConsistency()
        {
            var type    = typeof(ITwsEvents);
            var nUnique = type.GetMethods().Select(m => ((DispIdAttribute.GetCustomAttribute(m, typeof(DispIdAttribute)) as DispIdAttribute) ?? new DispIdAttribute(-1)).Value).Distinct().Count();

            Assert.AreEqual(type.GetMethods().Count(), nUnique, "Check ITwsEvents interface methods [DispId] attribute");
        }
Example #3
0
 /// <summary>
 /// Returns the COM DISPID of the given property.
 /// </summary>
 private static int GetPropertyDispId(Type type, string propertyName)
 {
     System.Reflection.PropertyInfo pi = type.GetProperty(propertyName);
     if (pi != null)
     {
         foreach (Attribute attribute in pi.GetCustomAttributes(true))
         {
             DispIdAttribute dispIdAttribute = attribute as DispIdAttribute;
             if (dispIdAttribute != null)
             {
                 return(dispIdAttribute.Value);
             }
         }
     }
     return(0);
 }
        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
        {
            if (attributeType == typeof(DispIdAttribute))
            {
                DispIdAttribute[] attribs = new DispIdAttribute[1];
                attribs[0] = new DispIdAttribute(_dispId);
                return(attribs);
            }

            if (attributeType == typeof(UserAnnotationAttribute))
            {
                return(_annotations.ToArray());
            }

            return(new object[0]);
        }
            int IComparer.Compare(object obj1, object obj2)
            {
                PropertyDescriptor descriptor  = obj1 as PropertyDescriptor;
                PropertyDescriptor descriptor2 = obj2 as PropertyDescriptor;
                DispIdAttribute    attribute   = descriptor.Attributes[typeof(DispIdAttribute)] as DispIdAttribute;
                DispIdAttribute    attribute2  = descriptor2.Attributes[typeof(DispIdAttribute)] as DispIdAttribute;

                if (attribute == null)
                {
                    return(1);
                }
                if (attribute2 == null)
                {
                    return(-1);
                }
                return(attribute.Value - attribute2.Value);
            }
            public CustomWebBrowserSite(CustomWebBrowser host)
                : base(host)
            {
                _host = host;

                _dispidCache = new Dictionary <int, PropertyInfo>();
                foreach (PropertyInfo pi in _host.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    if ((!pi.CanRead) || (pi.GetIndexParameters().Length > 0))
                    {
                        continue;
                    }
                    object[] atts = pi.GetCustomAttributes(typeof(DispIdAttribute), true);
                    if ((atts != null) && (atts.Length > 0))
                    {
                        DispIdAttribute da = (DispIdAttribute)atts[0];
                        _dispidCache[da.Value] = pi;
                    }
                }
            }
            internal AxPropertyDescriptor(PropertyDescriptor baseProp, AxHost owner) : base(baseProp)
            {
                this.baseProp = baseProp;
                this.owner    = owner;

                // Get the category for this dispid.
                //
                dispid = (DispIdAttribute)baseProp.Attributes[typeof(DispIdAttribute)];
                if (dispid != null)
                {
                    // Look to see if this property has a property page.
                    // If it does, then it needs to be Browsable(true).
                    //
                    if (!IsBrowsable && !IsReadOnly)
                    {
                        Guid g = GetPropertyPage((Ole32.DispatchID)dispid.Value);
                        if (!Guid.Empty.Equals(g))
                        {
                            Debug.WriteLineIf(AxPropTraceSwitch.TraceVerbose, "Making property: " + Name + " browsable because we found an property page.");
                            AddAttribute(new BrowsableAttribute(true));
                        }
                    }

                    // Use the CategoryAttribute provided by the OCX.
                    CategoryAttribute cat = owner.GetCategoryForDispid((Ole32.DispatchID)dispid.Value);
                    if (cat != null)
                    {
                        AddAttribute(cat);
                    }

                    // Check to see if this a DataSource property.
                    // If it is, we can always get and set the value of this property.
                    //
                    if (PropertyType.GUID.Equals(dataSource_Guid))
                    {
                        SetFlag(FlagIgnoreCanAccessProperties, true);
                    }
                }
            }
 public override object[] GetCustomAttributes(bool inherit)
 {
     DispIdAttribute[] attribs = new DispIdAttribute[1];
     attribs[0] = new DispIdAttribute(_dispId);
     return(attribs);
 }
Example #9
0
        /// <summary>
        /// 查找指定方法实现的接口成员并调用。
        /// </summary>
        /// <typeparam name="I">实现的接口</typeparam>
        /// <param name="mb">需要调用的方法</param>
        /// <param name="Params">参数</param>
        protected Task <RpcReturn> InvokeRemoteMemberAsync <I>(MethodBase mb, object[] Params)
        {
            if (mb == null)
            {
                throw new ArgumentNullException("mb");
            }

            // 取得指定方法实现的接口方法
            var im    = GetType().GetInterfaceMap(typeof(I));
            int index = Array.FindIndex(im.TargetMethods, (m) =>
            {
                return(m == (mb as MethodInfo));
            });

            if (index == -1)
            {
                throw new ArgumentException($"接口 {typeof(I).Name} 未定义成员 {mb.Name}。", "mb");
            }

            var BaseMethod = im.InterfaceMethods[index];
            // 验证参数是否对应

            /*var BaseMethod_Params = BaseMethod.GetParameters().Select(p => p.ParameterType).ToArray();
             * if (BaseMethod_Params.Length != Params.Length)// 验证参数数量是否对应
             *  throw new ArgumentException("提供的参数数量无法与指定接口的成员对应。");
             *
             * for (int i = 0; i != BaseMethod_Params.Length; i++)// 依次验证传入参数与接口方法参数类型是否对应
             * {
             *  if (Params[i] == null)
             *      continue;
             *
             *  System.Type ParamType = Params[i].GetType();
             *
             *  if (BaseMethod_Params[i].IsByRef && BaseMethod_Params[i].GetElementType() != ParamType)
             *  {
             *      // ref、out 类型的参数
             *      throw new ArgumentException();
             *  }
             *  if (BaseMethod_Params[i].IsArray && (!ParamType.IsArray || BaseMethod_Params[i].GetElementType() != ParamType))
             *  {
             *      // 数组
             *      throw new ArgumentException();
             *  }
             *  else if (BaseMethod_Params[i] != Params[i].GetType())
             *  {
             *      throw new ArgumentException();
             *  }
             * }*/

            // 获取 DispID 和 DispInvokeFlag
            DispIdAttribute dia = Attribute.GetCustomAttribute(BaseMethod, typeof(DispIdAttribute)) as DispIdAttribute;

            if (dia == null)
            {
                throw new ArgumentException($"{mb.Name} 不包含 DispIdAttribute 特性。", "mb");
            }

            int            DispID = dia.Value;
            DispInvokeFlag wFlags = 0;

            switch (BaseMethod.MemberType)
            {
            case MemberTypes.Method:
                wFlags = DispInvokeFlag.DISPATCH_METHOD;
                break;

            case MemberTypes.Property:
                break;

            case MemberTypes.Event:
                break;

            default:
                throw new ArgumentException("不支持的成员类型。");
            }

            var invoke = new RPC.RpcInvoke();

            invoke.InterfaceID = Crc32.Hash(typeof(I).GUID.ToByteArray(), 0, 16);
            invoke.CallID      = invoke.GetHashCode();
            invoke.ProxyID     = ProxyID;
            invoke.DispID      = DispID;
            invoke.WFlags      = (ushort)wFlags;
            foreach (var p in Params)
            {
                var vp = new VariantParam();

                if (p == null)
                {
                }
                else if (p is int || p is sbyte || p is short)
                {
                    vp.SFixed32 = (int)p;
                }
                else if (p is uint || p is byte || p is ushort)
                {
                    vp.Fixed32 = (uint)p;
                }
                else if (p is long)
                {
                    vp.SFixed64 = (long)p;
                }
                else if (p is ulong)
                {
                    vp.Fixed64 = (ulong)p;
                }
                else if (p is bool)
                {
                    vp.Bool = (bool)p;
                }
                else if (p is float)
                {
                    vp.Float = (float)p;
                }
                else if (p is double)
                {
                    vp.Double = (double)p;
                }
                else if (p is string)
                {
                    vp.String = p as string;
                }
                else if (p is decimal)
                {
                    vp.Decimal = p.ToString();
                }
                else if (p is byte[])
                {
                    vp.Bytes = ByteString.CopyFrom(p as byte[]);
                }
                else if (p is Guid)
                {
                    vp.Guid = ByteString.CopyFrom(((Guid)p).ToByteArray());
                }
                else if (p.GetType().GetInterfaces().FirstOrDefault(t => t == typeof(IMessage)) != null)
                {
                }
                else
                {
                    throw new ArgumentException();
                }

                invoke.Params.Add(vp);
            }

            return(m_HostContext.Invoke(invoke));
        }