Как отладчик / интерактивное окно Visual Studio выводит свойства COM-объектов в.NET?
В этом смежном вопросе я отметил, что отладчик Visual Studio может перечислять свойства System.__ComObject
ссылки, которые являются "скрытым типом, используемым, когда тип оболочки является неоднозначным" - например, тип объекта, который вы получаете, когда получаете его от другого COM-объекта и не создаете его экземпляр самостоятельно:
Кроме того, если вы просто запишите идентификатор COM-объекта в Immediate Window, его свойства и значения будут сброшены аналогичным образом:
Обратите внимание, что это отдельно от " Dynamic View " VS2010, который я считаю, использует IDispatch
и COM-отражение для перечисления свойств COM-объектов без использования PIA и.NET-отражения. Объекты, с которыми я работаю, не реализуются IDispatch
(и при этом они не реализуют IProvideClassInfo
В этом отношении "Dynamic View" не может получить никакой информации о них:
Интересно, что отладчик SharpDevelop не может перечислить членов System.__Comobject
s (например, point.Envelope
), только строго типизированные RCW (например, point
).
Итак, как Visual Studio может это сделать?
Я полагаю, что в этом случае это происходит потому, что существуют основные сборки взаимодействия с определениями интерфейсов, поддерживаемых этими объектами, и Visual Studio, вероятно, использует отражение для перечисления поддерживаемых интерфейсов и свойств. Это точно? И если так, как это работает?
Для начала, как он получает доступ к PIA? Он только смотрит на загруженные в настоящий момент PIA или динамически загружает их (и если да, то как)? Как это определяет, какой интерфейс, из которых может быть много, перечислить свойства? Кажется, он использует только один, а не обязательно первый. Из документации API, с которой я работаю (ArcObjects), интерфейс по умолчанию для этих объектов IUnknown
так что это не просто использование интерфейса по умолчанию.
В примере на скриншотах интерфейс, в котором перечисляются члены, является IEnvelope
интерфейс, который наследует от IGeometry
интерфейс. Как VS2010 знает не перечислять членов IGeometry
вместо этого, что, в моем тестировании, появляется первым, если вы просто перечислите все типы интерфейсов в PIA? Что-то очень умное происходит или, может быть, я упускаю что-то очевидное?
Причина, по которой я спрашиваю, заключается в том, что разработчик LINQPad, похоже, готов реализовать ту же функциональность, если бы он знал, как это делает VS. Таким образом, хороший ответ здесь может помочь улучшить этот очень популярный инструмент.
1 ответ
Вот как это сделать:
- получить COM-объект
IDispatch
(альтернативный возможный путьIDispatchEx
) - получить ссылку на библиотеку типов -
IDispatch::GetTypeInfo
- загрузить библиотеку типов и перечислить свойства
- запросить у реального объекта значения для обнаруженных свойств
Применяются дополнительные дополнительные возможности: запрос IPersist*
семейство интерфейсов или IProvideClassInfo
в качестве альтернативы получить ссылку на библиотеку типов для объекта и открыть свойства.