Есть ли способ избежать создания огромной оболочки интерфейса C # COM, когда нужно всего несколько методов? - PullRequest
3 голосов
/ 15 мая 2010

Привет всем,

Я работаю над программой на C #, для которой требуется получить индекс горячего элемента в новом элементе управления ViewView в Windows 7 Explorer. К счастью, Microsoft предоставила способ сделать это с помощью автоматизации пользовательского интерфейса, запросив пользовательские свойства элемента управления.

К сожалению, пространство имен System.Windows.Automation необъяснимым образом не обеспечивает способ запроса пользовательских свойств! Это оставляет меня с нежелательной позицией необходимости полностью отказаться от пространства имен C # Automation и использовать только неуправляемую версию COM. Один из способов сделать это - поместить весь код автоматизации в отдельный модуль C ++ / CLI и вызвать его из моего приложения на C #. Тем не менее, я хотел бы по возможности избежать этой опции, так как она добавляет больше файлов в мой проект, и мне придется беспокоиться о проблемах с 32/64-битными и другими.

Другой вариант - использовать атрибут ComImport для объявления соответствующих интерфейсов и делать все через COM-взаимодействие. Это то, что я хотел бы сделать. Однако соответствующие интерфейсы, такие как IUIAutomation и IUIAutomationElement, являются ОГРОМНЫМИ. В общей сложности у них есть сотни методов и ссылки на тонны и тонны интерфейсов (которые, я полагаю, я должен был бы также объявить), почти все из которых я никогда не буду использовать. Я не думаю, что интерфейсы автоматизации пользовательского интерфейса объявлены в любой библиотеке типов, поэтому я не могу использовать TLBIMP.

Можно ли как-нибудь избежать ручного перевода сигнатур метода bajillion в C # и вместо этого объявить только десять или около того методов, которые мне действительно нужны? Я вижу, что C # 4.0 добавил новый «динамический» тип, который должен облегчить взаимодействие COM; это вообще относится к моей проблеме?

Спасибо

1 Ответ

7 голосов
/ 15 мая 2010

Самое важное (с точки зрения вызова COM-метода из C #) заключается в том, что методы отображаются в интерфейсе в правильном порядке. Если вы не используете метод, вы можете просто объявить его как void, и ничего плохого не произойдет (если вы на самом деле не вызываете его!). Это избавляет вас от необходимости разрабатывать правильные подписи и определять все другие типы и т. Д. Например,

[ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IUIAutomation
{
    void CompareElements();
    void CompareRuntimeIds();
    void GetRootElement();
    // 50 or so other methods...
    // ... define only the signatures for the ones you actually need
}

Методы должны быть определены в том же порядке, в котором они появляются в UIAutomationClient.h (в Windows SDK).

...