反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
#3
method值一直为空额,哪怕里面有那个方法也是
#4
不行啊,判断不出来啊,是否有这个方法
#5
//通过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"));
}
#6
type有值没?
#7
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
//通过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每值,一直是空
#8
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
type有值没?
type一直没值!~~
#9
comObj.GetType().GetMembers()
看有哪些MemberName
#10
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
type有值没?
type有值 但是method一直为空。。
#11
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
关于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即表示不存在了,上面那个代码里有现成的接口声明,贴给你吧
#27
public static class DispatchUtility
{
#region Private Constants
/// <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>
/// <remarks>
/// 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.
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
/// </remarks>
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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
/// </remarks>
[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;
}
#28
public static class DispatchUtility
{
#region Private Constants
/// <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>
/// <remarks>
/// 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.
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
/// </remarks>
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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
/// </remarks>
[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"))就行了
如果这都看不懂,那你只好去补一下基础了
#32
你把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"))就行了
如果这都看不懂,那你只好去补一下基础了
结贴,谢谢了。
#1
comObj.GetType().GetMember(_methodName)
#2
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
#3
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
#4
comObj.GetType().GetMember(_methodName)
不行啊,判断不出来啊,是否有这个方法
#5
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
//通过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"));
}
#6
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
type有值没?
#7
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
//通过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每值,一直是空
#8
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
type有值没?
type一直没值!~~
#9
comObj.GetType().GetMembers()
看有哪些MemberName
#10
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
method值一直为空额,哪怕里面有那个方法也是
type有值没?
type有值 但是method一直为空。。
#11
反射呗
var type = Type.GetTypeFromCLSID(new Guid("30FB1E22-B498-4B62-8B26-98BA61176024"));
var method = type.GetMethod(_methodName, 是否区分大小写);
if(method != null)
{
method.Invoke(XXX)
}
关于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即表示不存在了,上面那个代码里有现成的接口声明,贴给你吧
#27
public static class DispatchUtility
{
#region Private Constants
/// <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>
/// <remarks>
/// 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.
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
/// </remarks>
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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
/// </remarks>
[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;
}
#28
public static class DispatchUtility
{
#region Private Constants
/// <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>
/// <remarks>
/// 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.
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
/// </remarks>
[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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
/// </remarks>
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>
/// <remarks>
/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
/// </remarks>
[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"))就行了
如果这都看不懂,那你只好去补一下基础了
#32
你把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"))就行了