2012-05-16 8 views
14

Làm cách nào để đọc tất cả tên thuộc tính thông qua phản ánh đối tượng COM trong C#? Tôi biết cách nhận tài sản nếu tôi biết tên.Nhận tên thuộc tính thông qua sự phản ánh của đối tượng COM

comObject.GetType().InvokeMember("PropertyName", System.Reflection.BindingFlags.GetProperty, null, comObject, null); 

nhưng khi nào tôi muốn đổ tất cả các thuộc tính?

PropertyInfo[] properties = t.GetProperties(); 

Cách này không hoạt động với Com-Objects. Nếu tôi làm một GetMembers() tôi nhận được những viên:

Name: GetLifetimeService 
Name: InitializeLifetimeService 
Name: CreateObjRef 
Name: ToString 
Name: Equals 
Name: GetHashCode 
Name: GetType 

coi Chris

+2

Nó không rõ ràng những gì bạn đang yêu cầu, bởi vì bạn đã cung cấp câu trả lời. 'GetProperties' sẽ trả về tất cả các thuộc tính của một kiểu. –

+0

Vâng, 'PropertyInfo.Name'? –

+2

Nhưng không phải của một đối tượng COM! –

Trả lời

12

Bạn có các thành viên của lớp __ComObject, lớp .NET cơ bản cho một RCW.

COM có hỗ trợ bit wee để phản chiếu, miễn là COM coclass triển khai IDispatch, giao diện Tự động hóa. Không bình thường, đó là giao diện mà các ngôn ngữ kịch bản sử dụng để thực hiện cuộc gọi. IDispatch.GetIDsOfNames() luôn được triển khai, nhưng bạn phải biết tên của thành viên ở phía trước. IDispatch.GetTypeInfo() cho phép truy cập vào thư viện kiểu cho coclass, nhưng không phải lúc nào cũng được triển khai. Bản dịch của loại thông tin thư viện để siêu dữ liệu là một nghệ thuật không hoàn hảo, lý do cốt lõi tại sao .NET muốn bạn làm điều này trả trước với Tlbimp.exe. Nếu bạn muốn theo đuổi một cách tiếp cận thời gian chạy thì có thể bạn sẽ được hưởng lợi từ nguồn cho phiên bản được quản lý của Tlbimp, available here.

Thực hiện điều này trước khi xây dựng luôn tốt nhất, bạn làm như vậy bằng cách thêm tham chiếu vào thư viện kiểu (thường được nhúng trong tệp thi hành) hoặc bằng cách chạy Tlbimp.exe. Bây giờ bạn đã có một lớp bao bọc .NET interop có tất cả các thành viên của COM coclass và giao diện cơ bản. Tại thời điểm đó bạn có thể không cần phản ánh nữa :)

10

Tôi vừa mới xuất bản một bài viết về CodeProject về cách thực hiện Reflection with IDispatch-based COM objects. Bài viết cung cấp một lớp trợ giúp C# DispatchUtility nhỏ dễ dàng đưa vào các dự án khác. Bên trong, nó sử dụng một khai báo tùy chỉnh của IDispatch và TypeToTypeInfoMarshaler của .NET để chuyển đổi ITypeInfo của IDispatch thành một cá thể .NET Type phong phú.

Trong ví dụ của bạn, bạn có thể gọi DispatchUtility.GetType(comObject, true) để quay lại phiên bản Loại .NET, sau đó bạn có thể gọi GetProperties hoặc GetMembers.

Tôi cũng đã cung cấp một phiên bản mã nguồn DispatchUtility trên StackOverflow trong một phản ứng để How to enumerate members of COM object in C#?

+0

Cảm ơn bạn vì bài viết tuyệt vời. Tôi đã thử sử dụng nó nhưng phải đối mặt với một vấn đề. Tôi nhận được lỗi: "loại thư viện đã được xuất khẩu từ một hội đồng clr và không thể được nhập khẩu lại" Tôi đang sử dụng Activator.createInstance để tạo đối tượng. Công cụ mà tôi đang tạo đối tượng COM là Tibco Spotfire v6.5.2 Bạn có thể vui lòng trợ giúp không. Cảm ơn – Prabhakar

+0

@Bill Menees, lớp trợ giúp của bạn có thể được sử dụng trong [PowerShell để tạo đối tượng của đối tượng COM] (http://stackoverflow.com/questions/41945859/use-powershell-to-create-instance-of-com-object)? – craig