解决方案 »

  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.   

    method值一直为空额,哪怕里面有那个方法也是
      

  4.   

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

  5.   

    method值一直为空额,哪怕里面有那个方法也是
     type有值没?
      

  6.   

       //通过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每值,一直是空
      

  7.   

    method值一直为空额,哪怕里面有那个方法也是
     type有值没?
    type一直没值!~~
      

  8.   

    comObj.GetType().GetMembers()
    看有哪些MemberName
      

  9.   

    method值一直为空额,哪怕里面有那个方法也是
     type有值没?
    type有值 但是method一直为空。。
      

  10.   

    method值一直为空额,哪怕里面有那个方法也是
     type有值没?
    type一直没值!~~
    type一直没值,那执行GetMethod肯定反射不来东东啊
    是不是你的GUID搞错了
      

  11.   

    {System.String ToString()}
    System.Object GetLifetimeService
    System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)
    等等一共6个值!~
      

  12.   

    method值一直为空额,哪怕里面有那个方法也是
     type有值没?
    type一直没值!~~
    type一直没值,那执行GetMethod肯定反射不来东东啊
    是不是你的GUID搞错了
    type有值,method没值!~一直是空
      

  13.   

    GetMethod用法,是不是2#搞错了。
    照着msdn的例子用
    http://msdn.microsoft.com/zh-cn/library/6hy0h0z1(v=vs.100).aspx
      

  14.   

     额,这个getMethod是调用方法啊?我要的只查询出这个方法是否存在于这个类中!· = = 
      

  15.   


      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));整体代码。。
      

  16.   

    没用啊版主,找不到那个guid类当中的那些方法!~~~
      

  17.   

     额,这个getMethod是调用方法啊?我要的只查询出这个方法是否存在于这个类中!· = = 
    无语了~~~GetMethod从类型里面反射出某个方法是否存在
    类型.GetMethod返回结果不是null,就证明这个类型中存在这个方法了
      

  18.   

     额,这个getMethod是调用方法啊?我要的只查询出这个方法是否存在于这个类中!· = = 
    无语了~~~GetMethod从类型里面反射出某个方法是否存在
    类型.GetMethod返回结果不是null,就证明这个类型中存在这个方法了
    不是吧?我看csdn里面是写的方法名加参数,得到的是返回结果额?
    但是我那个类中确实存在那个方法。method还是为空!~
      

  19.   

    如果那个方法没有重载过,是不需要指定参数及类型的,你确定总共就6个成员吗?那样就不是GetMethod的问题了,反射出来的都是托管类型的成员,不是COM接口的成员
    当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
      

  20.   

    Com对象在.net这边的类型其实是System.__ComObject,所以通过GetMethods这样反射是取不到信息的。
    必须使用Com的IDispatch接口上面的GetIDsOfNames才能判断
      

  21.   

    可以使用这里面提供的代码:http://www.codeproject.com/Articles/523417/Reflection-with-IDispatch-based-COM-objects
      

  22.   

    不该DLL文件能实现吗?只要能判断出这个方法到底存在不存在就ok
      

  23.   

    其实思路也不复杂
    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即表示不存在了,上面那个代码里有现成的接口声明,贴给你吧
      

  24.   


    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;
    }
      

  25.   

    哥们,这个是改的C++端的程序吗? 有点晕。- -有没有其他什么方式能判断呢。只要是能查询出这个方法是否存在于这个dll当中就可以。!
      

  26.   

    不是C++端的,就是C#中判断COM组件是否包含某个成员的方法
      

  27.   

    你把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"))就行了如果这都看不懂,那你只好去补一下基础了