反射呗 var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024")); var method = type.GetMethod(_methodName, 是否区分大小写); if(method != null) { method.Invoke(XXX) }
method值一直为空额,哪怕里面有那个方法也是
//通过GUID获取到DVBusiUtilCalClass类 var type=Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024")); //查看是否有—_methodName这个方法 var method = type.GetMethod(_methodName); 如果在DVBusiUtilCalClass没有找到这个方法,那么去创建DVBusiUtilPreClass的实例 if (method == null) { type = Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA")); }
method值一直为空额,哪怕里面有那个方法也是 type有值没?
//通过GUID获取到DVBusiUtilCalClass类 var type=Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024")); //查看是否有—_methodName这个方法 var method = type.GetMethod(_methodName); 如果在DVBusiUtilCalClass没有找到这个方法,那么去创建DVBusiUtilPreClass的实例 if (method == null) { type = Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA")); } type有值,但是method每值,一直是空
关于DISPID的进一步说明: typedef LONG DISPID; typedef DISPID MEMBERID;
DISPID小于等于0的值都是有特殊意义的,如下面介绍的---- /* DISPID reserved to indicate an "unknown" name */ /* only reserved for data members (properties); reused as a method dispid below */ //如果GetIDsOfNames函数找不到与名称相对应的DISPID,返回该值 #define DISPID_UNKNOWN ( -1 )所以当输出参数rgDispId == -1即表示不存在了,上面那个代码里有现成的接口声明,贴给你吧
public static class DispatchUtility { #region Private Constants private const int S_OK = 0; //From WinError.h private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800 #endregion #region Public Methods /// <summary> /// Gets whether the specified object implements IDispatch. /// </summary> /// <param name="obj">An object to check.</param> /// <returns>True if the object implements IDispatch. False otherwise.</returns> public static bool ImplementsIDispatch(object obj) { bool result = obj is IDispatchInfo; return result; } /// <summary> /// Gets a Type that can be used with reflection. /// </summary> /// <param name="obj">An object that implements IDispatch.</param> /// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param> /// <returns>A .NET Type that can be used with reflection.</returns> /// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception> [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static Type GetType(object obj, bool throwIfNotFound) { RequireReference(obj, "obj"); Type result = GetType((IDispatchInfo)obj, throwIfNotFound); return result; } /// <summary> /// Tries to get the DISPID for the requested member name. /// </summary> /// <param name="obj">An object that implements IDispatch.</param> /// <param name="name">The name of a member to lookup.</param> /// <param name="dispId">If the method returns true, this holds the DISPID on output. /// If the method returns false, this value should be ignored.</param> /// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns> /// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception> [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] public static bool TryGetDispId(object obj, string name, out int dispId) { RequireReference(obj, "obj"); bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId); return result; } #region Private Methods /// <summary> /// Requires that the value is non-null. /// </summary> /// <typeparam name="T">The type of the value.</typeparam> /// <param name="value">The value to check.</param> /// <param name="name">The name of the value.</param> private static void RequireReference<T>(T value, string name) where T : class { if (value == null) { throw new ArgumentNullException(name); } } /// <summary> /// Gets a Type that can be used with reflection. /// </summary> /// <param name="dispatch">An object that implements IDispatch.</param> /// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param> /// <returns>A .NET Type that can be used with reflection.</returns> private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound) { RequireReference(dispatch, "dispatch"); Type result = null; int typeInfoCount; int hr = dispatch.GetTypeInfoCount(out typeInfoCount); if (hr == S_OK && typeInfoCount > 0) { // Type info isn't usually culture-aware for IDispatch, so we might as well pass // the default locale instead of looking up the current thread's LCID each time // (via CultureInfo.CurrentCulture.LCID). dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result); } if (result == null && throwIfNotFound) { // If the GetTypeInfoCount called failed, throw an exception for that. Marshal.ThrowExceptionForHR(hr); // Otherwise, throw the same exception that Type.GetType would throw. throw new TypeLoadException(); } return result; } /// <summary> /// Tries to get the DISPID for the requested member name. /// </summary> /// <param name="dispatch">An object that implements IDispatch.</param> /// <param name="name">The name of a member to lookup.</param> /// <param name="dispId">If the method returns true, this holds the DISPID on output. /// If the method returns false, this value should be ignored.</param> /// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns> private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId) { RequireReference(dispatch, "dispatch"); RequireReference(name, "name"); bool result = false; // Members names aren't usually culture-aware for IDispatch, so we might as well // pass the default locale instead of looking up the current thread's LCID each time // (via CultureInfo.CurrentCulture.LCID). Guid iidNull = Guid.Empty; int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId); const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h const int DISPID_UNKNOWN = -1; //From OAIdl.idl if (hr == S_OK) { result = true; } else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN) { // This is the only supported "error" case because it means IDispatch // is saying it doesn't know the member we asked about. result = false; } else { // The other documented result codes are all errors. Marshal.ThrowExceptionForHR(hr); } return result; } #endregion #region Private Interfaces /// <summary> /// A partial declaration of IDispatch used to lookup Type information and DISPIDs. /// </summary> /// <res> /// This interface only declares the first three methods of IDispatch. It omits the /// fourth method (Invoke) because there are already plenty of ways to do dynamic /// invocation in .NET. But the first three methods provide dynamic type metadata /// discovery, which .NET doesn't provide normally if you have a System.__ComObject /// RCW instead of a strongly-typed RCW. /// <para/> /// Note: The original declaration of IDispatch is in OAIdl.idl. /// </res> [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("00020400-0000-0000-C000-000000000046")] private interface IDispatchInfo { /// <summary> /// Gets the number of Types that the object provides (0 or 1). /// </summary> /// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param> /// <res> /// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85) /// </res> [PreserveSig] int GetTypeInfoCount(out int typeInfoCount); /// <summary> /// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1. /// </summary> /// <param name="typeInfoIndex">Must be 0.</param> /// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param> /// <param name="typeInfo">Returns the object's Type information.</param> /// <res> /// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85) /// </res> void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo); /// <summary> /// Gets the DISPID of the specified member name. /// </summary> /// <param name="riid">Must be IID_NULL. Pass a copy of Guid.Empty.</param> /// <param name="name">The name of the member to look up.</param> /// <param name="nameCount">Must be 1.</param> /// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param> /// <param name="dispId">If a member with the requested <paramref name="name"/> /// is found, this returns its DISPID and the method's return value is 0. /// If the method returns a non-zero value, then this parameter's output value is /// undefined.</param> /// <returns>Zero for success. Non-zero for failure.</returns> /// <res> /// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85) /// </res> [PreserveSig] int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId); // NOTE: The real IDispatch also has an Invoke method next, but we don't need it. // We can invoke methods using .NET's Type.InvokeMember method with the special // [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo // and invoke methods on that through reflection. // Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx } #endregion }if (!DispatchUtility.ImplementsIDispatch(obj)) { throw new ArgumentException("The object created for " + progId + " doesn't implement IDispatch."); }// See if we can get Type info and then do some reflection. Type dispatchType = DispatchUtility.GetType(obj, false); if (dispatchType != null) { var hr = DispatchUtility.TryGetDispId(obj, _methodName, out dispId); return hr== hr_OK && dispId != -1; }
你把DispatchUtility这个类复制到你的项目中,然后用 if (!DispatchUtility.ImplementsIDispatch(obj)) { throw new ArgumentException("The object created for " + progId + " doesn't implement IDispatch."); } // See if we can get Type info and then do some reflection. Type dispatchType = DispatchUtility.GetType(obj, false); int dispId; if (dispatchType != null) { var hr = DispatchUtility.TryGetDispId(obj, _methodName, out dispId); return hr== 0 && dispId != -1; }obj就是com对象,其实是不需要obj的,有var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"))就行了如果这都看不懂,那你只好去补一下基础了
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
var type=Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
//查看是否有—_methodName这个方法
var method = type.GetMethod(_methodName);
如果在DVBusiUtilCalClass没有找到这个方法,那么去创建DVBusiUtilPreClass的实例
if (method == null)
{
type = Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA"));
}
type有值没?
var type=Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
//查看是否有—_methodName这个方法
var method = type.GetMethod(_methodName);
如果在DVBusiUtilCalClass没有找到这个方法,那么去创建DVBusiUtilPreClass的实例
if (method == null)
{
type = Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA"));
}
type有值,但是method每值,一直是空
type有值没?
type一直没值!~~
看有哪些MemberName
type有值没?
type有值 但是method一直为空。。
type有值没?
type一直没值!~~
type一直没值,那执行GetMethod肯定反射不来东东啊
是不是你的GUID搞错了
System.Object GetLifetimeService
System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)
等等一共6个值!~
type有值没?
type一直没值!~~
type一直没值,那执行GetMethod肯定反射不来东东啊
是不是你的GUID搞错了
type有值,method没值!~一直是空
照着msdn的例子用
http://msdn.microsoft.com/zh-cn/library/6hy0h0z1(v=vs.100).aspx
args[0] = "DVC_CutImgmethod";
args[1] = @"11";
args[2] = "1";
args[3] = "2";
//如果没有数据的话,直接return
if (args.Length == 0)
{
return;
}
//获取方法名
string _methodName = args[0];
//创建list集合用于保存参数
List<object> list = new List<object>(); for (int i = 1; i < args.Length; i++)
{
list.Add(args[i]);
}
//转换成object数组
object[] param = list.ToArray();
//通过GUID获取到DVBusiUtilCalClass类
var type=Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
//查看是否有—_methodName这个方法
var method = type.GetMethod(_methodName);
MethodInfo[] sss= type.GetMethods();
//如果在DVBusiUtilCalClass没有找到这个方法,那么去创建DVBusiUtilPreClass的实例
if (method == null)
{
type = Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA"));
}
object comObj = Activator.CreateInstance(type);
//创建类型实例
//object comObj = Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024")));
//MemberInfo[] vvv = comObj.GetType().GetMembers();
//int ddd = vvv.Length;
//if (comObj.GetType().GetMember(_methodName)==null)
//{
// comObj = Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("592703AB-CF61-425D-9ACD-A0938E451AEA")));
//}
//获取返回值
object result = comObj.GetType().InvokeMember(_methodName, System.Reflection.BindingFlags.InvokeMethod, null, comObj, param);
Console.WriteLine(Convert.ToInt32(result));整体代码。。
无语了~~~GetMethod从类型里面反射出某个方法是否存在
类型.GetMethod返回结果不是null,就证明这个类型中存在这个方法了
无语了~~~GetMethod从类型里面反射出某个方法是否存在
类型.GetMethod返回结果不是null,就证明这个类型中存在这个方法了
不是吧?我看csdn里面是写的方法名加参数,得到的是返回结果额?
但是我那个类中确实存在那个方法。method还是为空!~
当COM类实现了IDispatch意味着将延迟绑定类型
IDispatch::GetIDsOfNames 方法,Visual C# 可以询问对象支持哪些方法和属性
IDispatch::Invoke 方法允许 Visual C# 调用这些方法和属性。不过NET封装了现成的try
{
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
type.InvokeMember(_methodName, BindingFlags.InvokeMethod, null, comObj, 参数列表);
}
catch(System.MissingMethodException exp)
{
方法未找到
}找到了一篇C++通过IDispatch查询并调用的文章,你可以看看,
http://blog.csdn.net/csfreebird/article/details/463031
必须使用Com的IDispatch接口上面的GetIDsOfNames才能判断
1. 定义一个IDispatch
2. 获取IDispatch指针对象
3.利用IDispatch.GetIDsOfNames来判断成员是否存在(当然先要用GetTypeInfoCount(out count)判断是否具有类型信息)HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId)
IDispatch接口的属性实质上是方法,方法也就是成员函数,IDispatch接口把所有成员函数的入口地址放入到一个数组中,并且内部组织了一个Map,将数组索引和方法名称一一映射。我们常见的DISPID就是这些方法在数组中的索引。如果我们想调用某一个方法,我们就需要DISPID来让我们找到该方法的地址。
参数riid必须为NULL。
参数rgszNames为字符串数组,第一个字符串为方法或者属性的名称,后续的字符串为参数名称,IDispatch接口的参数也可以有名字。
参数cNames指定rgszNames数组中字符串的个数。
参数lcid传递地域标志,同GetTypeInfo方法中的参数。
参数rgDispId输出一个数组,每个数组成员对应rgszNames中的一个字符串名称。
关于DISPID的进一步说明:
typedef LONG DISPID;
typedef DISPID MEMBERID;
DISPID小于等于0的值都是有特殊意义的,如下面介绍的----
/* DISPID reserved to indicate an "unknown" name */
/* only reserved for data members (properties); reused as a method dispid below */
//如果GetIDsOfNames函数找不到与名称相对应的DISPID,返回该值
#define DISPID_UNKNOWN ( -1 )所以当输出参数rgDispId == -1即表示不存在了,上面那个代码里有现成的接口声明,贴给你吧
public static class DispatchUtility
{
#region Private Constants private const int S_OK = 0; //From WinError.h
private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800 #endregion #region Public Methods /// <summary>
/// Gets whether the specified object implements IDispatch.
/// </summary>
/// <param name="obj">An object to check.</param>
/// <returns>True if the object implements IDispatch. False otherwise.</returns>
public static bool ImplementsIDispatch(object obj)
{
bool result = obj is IDispatchInfo;
return result;
} /// <summary>
/// Gets a Type that can be used with reflection.
/// </summary>
/// <param name="obj">An object that implements IDispatch.</param>
/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
/// <returns>A .NET Type that can be used with reflection.</returns>
/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static Type GetType(object obj, bool throwIfNotFound)
{
RequireReference(obj, "obj");
Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
return result;
} /// <summary>
/// Tries to get the DISPID for the requested member name.
/// </summary>
/// <param name="obj">An object that implements IDispatch.</param>
/// <param name="name">The name of a member to lookup.</param>
/// <param name="dispId">If the method returns true, this holds the DISPID on output.
/// If the method returns false, this value should be ignored.</param>
/// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns>
/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static bool TryGetDispId(object obj, string name, out int dispId)
{
RequireReference(obj, "obj");
bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
return result;
} #region Private Methods /// <summary>
/// Requires that the value is non-null.
/// </summary>
/// <typeparam name="T">The type of the value.</typeparam>
/// <param name="value">The value to check.</param>
/// <param name="name">The name of the value.</param>
private static void RequireReference<T>(T value, string name) where T : class
{
if (value == null)
{
throw new ArgumentNullException(name);
}
} /// <summary>
/// Gets a Type that can be used with reflection.
/// </summary>
/// <param name="dispatch">An object that implements IDispatch.</param>
/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
/// <returns>A .NET Type that can be used with reflection.</returns>
private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
{
RequireReference(dispatch, "dispatch"); Type result = null;
int typeInfoCount;
int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
if (hr == S_OK && typeInfoCount > 0)
{
// Type info isn't usually culture-aware for IDispatch, so we might as well pass
// the default locale instead of looking up the current thread's LCID each time
// (via CultureInfo.CurrentCulture.LCID).
dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
} if (result == null && throwIfNotFound)
{
// If the GetTypeInfoCount called failed, throw an exception for that.
Marshal.ThrowExceptionForHR(hr); // Otherwise, throw the same exception that Type.GetType would throw.
throw new TypeLoadException();
} return result;
} /// <summary>
/// Tries to get the DISPID for the requested member name.
/// </summary>
/// <param name="dispatch">An object that implements IDispatch.</param>
/// <param name="name">The name of a member to lookup.</param>
/// <param name="dispId">If the method returns true, this holds the DISPID on output.
/// If the method returns false, this value should be ignored.</param>
/// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns>
private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
{
RequireReference(dispatch, "dispatch");
RequireReference(name, "name"); bool result = false; // Members names aren't usually culture-aware for IDispatch, so we might as well
// pass the default locale instead of looking up the current thread's LCID each time
// (via CultureInfo.CurrentCulture.LCID).
Guid iidNull = Guid.Empty;
int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId); const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
const int DISPID_UNKNOWN = -1; //From OAIdl.idl
if (hr == S_OK)
{
result = true;
}
else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
{
// This is the only supported "error" case because it means IDispatch
// is saying it doesn't know the member we asked about.
result = false;
}
else
{
// The other documented result codes are all errors.
Marshal.ThrowExceptionForHR(hr);
} return result;
} #endregion #region Private Interfaces /// <summary>
/// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
/// </summary>
/// <res>
/// This interface only declares the first three methods of IDispatch. It omits the
/// fourth method (Invoke) because there are already plenty of ways to do dynamic
/// invocation in .NET. But the first three methods provide dynamic type metadata
/// discovery, which .NET doesn't provide normally if you have a System.__ComObject
/// RCW instead of a strongly-typed RCW.
/// <para/>
/// Note: The original declaration of IDispatch is in OAIdl.idl.
/// </res>
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00020400-0000-0000-C000-000000000046")]
private interface IDispatchInfo
{
/// <summary>
/// Gets the number of Types that the object provides (0 or 1).
/// </summary>
/// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
/// <res>
/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
/// </res>
[PreserveSig]
int GetTypeInfoCount(out int typeInfoCount); /// <summary>
/// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
/// </summary>
/// <param name="typeInfoIndex">Must be 0.</param>
/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
/// <param name="typeInfo">Returns the object's Type information.</param>
/// <res>
/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
/// </res>
void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo); /// <summary>
/// Gets the DISPID of the specified member name.
/// </summary>
/// <param name="riid">Must be IID_NULL. Pass a copy of Guid.Empty.</param>
/// <param name="name">The name of the member to look up.</param>
/// <param name="nameCount">Must be 1.</param>
/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
/// <param name="dispId">If a member with the requested <paramref name="name"/>
/// is found, this returns its DISPID and the method's return value is 0.
/// If the method returns a non-zero value, then this parameter's output value is
/// undefined.</param>
/// <returns>Zero for success. Non-zero for failure.</returns>
/// <res>
/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
/// </res>
[PreserveSig]
int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId); // NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
// We can invoke methods using .NET's Type.InvokeMember method with the special
// [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
// and invoke methods on that through reflection.
// Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
}
#endregion
}if (!DispatchUtility.ImplementsIDispatch(obj))
{
throw new ArgumentException("The object created for " + progId + " doesn't implement IDispatch.");
}// See if we can get Type info and then do some reflection.
Type dispatchType = DispatchUtility.GetType(obj, false);
if (dispatchType != null)
{
var hr = DispatchUtility.TryGetDispId(obj, _methodName, out dispId);
return hr== hr_OK && dispId != -1;
}
if (!DispatchUtility.ImplementsIDispatch(obj))
{
throw new ArgumentException("The object created for " + progId + " doesn't implement IDispatch.");
}
// See if we can get Type info and then do some reflection.
Type dispatchType = DispatchUtility.GetType(obj, false);
int dispId;
if (dispatchType != null)
{
var hr = DispatchUtility.TryGetDispId(obj, _methodName, out dispId);
return hr== 0 && dispId != -1;
}obj就是com对象,其实是不需要obj的,有var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"))就行了如果这都看不懂,那你只好去补一下基础了