2011-11-09 27 views
5

Tôi muốn gọi hàm GetIdsOfNames từ đối tượng COM thực hiện giao diện IDispatch trong C#. Tôi đã viết mã sau nhưng nó không thành công với DISP_E_UNKNOWNNAME. Đây có phải là cách tiếp cận chính xác để thực hiện việc này không?Gọi một thành viên của giao diện IDispatch COM từ C#

Object so = Activator.CreateInstance(Type.GetTypeFromProgID("ProgID"));    
Object[] args = new Object[5]; 
string[] rgsNames = new string[1]; 
rgsNames[0] = "PrintNormal"; 
uint LOCALE_SYSTEM_DEFAULT = 0x0800; 
uint lcid = LOCALE_SYSTEM_DEFAULT; 
int cNames = 1; 
int[] rgDispId = new int[1]; 
args[0] = IntPtr.Zero; 
args[1] = rgsNames; 
args[2] = cNames; 
args[3] = lcid; 
args[4] = rgDispId;    
Object result = so.GetType().InvokeMember("GetIDsOfNames", BindingFlags.InvokeMethod, null, so, args); 

Cảm ơn,

Richard

Trả lời

4

Không bạn không thể, bởi vì InvokeMember nội bộ sử dụng GetIDsOfNames, và điều này chỉ kiểm tra các phương pháp thực tế, không phải là 6 đầu tiên trong IDispatch. Hay nói cách khác, GetIDsOfNames không thể được gọi bằng phương thức gọi của IDispatch. Đó là cách COM hoạt động.

21

Có, không hoạt động, RCW không hiển thị các phương pháp IDispatch. Bạn phải có được tham chiếu giao diện IDispatch một cách rõ ràng. Điều này hoạt động tốt:

using System; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 

class Program { 
    static void Main() { 
     Object so = Activator.CreateInstance(Type.GetTypeFromProgID("SAPI.SpVoice")); 
     string[] rgsNames = new string[1]; 
     int[] rgDispId = new int[1]; 
     rgsNames[0] = "Speak"; 
     IDispatch disp = (IDispatch)so; 
     Guid dummy = Guid.Empty; 
     disp.GetIDsOfNames(ref dummy, rgsNames, 1, 0x800, rgDispId); 
     Console.WriteLine(rgDispId[0]); 
    } 

    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")] 
    private interface IDispatch { 
     int GetTypeInfoCount(); 
     [return: MarshalAs(UnmanagedType.Interface)] 
     ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid); 
     void GetIDsOfNames([In] ref Guid riid, [In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames, [In, MarshalAs(UnmanagedType.U4)] int cNames, [In, MarshalAs(UnmanagedType.U4)] int lcid, [Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId); 
    } 
} 
+0

cảm ơn. Thats thực sự thực sự hữu ích. –

Các vấn đề liên quan