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); }
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"); }
/// <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); }
/// <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)); }