Во-первых, не используйте DTE, если можете. Это очень неполная, шаткая абстракция, прикрытая чрезвычайно сложным интерфейсом. Сказав это, я признаю, что иногда это очень удобно, потому что либо эквивалент не может быть сделан без него (редко), либо альтернативный код будет довольно длинным (реже редко).
Здесь смешиваются два понятия. Первая — это рабочая таблица документов (RDT). RDT представляет все открытые файлы (включая открытые .sln и файлы проекта). Вы можете подписаться на события RDT, чтобы получать уведомления об открытии, закрытии, переименовании файлов и т. д. Но эти события предназначены только для открытых файлов!
Вторая концепция – это проектная система. Каждый проект, загружаемый и отображаемый в обозревателе решений, загружается системой проектов для этого типа проекта. Проекты C++, проекты C#, проекты F#, проекты установщика WIX и т. д. — все они имеют разные системы проектов. Могут быть даже пользовательские системы проектов, реализованные расширениями. Похоже, вы хотите знать о событиях в системе проектов, а не о событиях (просто) открытых файлов. Итак, вы сосредоточены на системе проектов. Однако, поскольку все системы проектов имеют разные реализации, это становится очень сложной задачей. VS движется в сторону общей системы проектов (CPS), но ее еще нет на 100%, и даже когда она есть остается проблема всех устаревших расширений и т.д.
Вы можете подписаться на общие события "иерархии", которые должны предоставляться всеми системами проекта. Например, они сообщат вам, когда файл добавляется или удаляется (на самом деле, когда элемент иерархии (узел) добавляется или удаляется, поскольку между файлами и элементами иерархии не обязательно существует соответствие). Также есть событие, в котором сообщается, что вся иерархия признана недействительной — своего рода обновление, когда вам нужно отбросить все, что вы знаете о проекте, и собрать новую информацию.
Переименование, пожалуй, труднее всего обнаружить. Каждая проектная система реализует его по-своему. В некоторых системах проектов переименование будет представлять собой удаление узла, за которым следует добавление узла, без надежного способа определить, что это произошло из-за переименования.
Подводя итог, можно сказать, что все не так просто, как кажется, особенно когда речь идет о системах проектов (одна из наименее расширяемых частей Visual Studio). Скорее всего, вы получите код, который специфичен для одной или нескольких систем проектов, но не будет работать повсеместно. (В конце концов, не все проекты даже представляют файловые иерархии! А в тех, которые все же есть, есть папки, специальные ссылочные узлы и т. д., которые не являются файлами.)
Некоторые конкретные указатели в правильном направлении:
- Реализуйте
IVsSolutionEvents3
, чтобы получать уведомления о загрузке/выгрузке проекта (и IVsSolutionEvents4
, чтобы получать уведомления о переименовании самого проекта). Зарегистрируйте этот объект в качестве слушателя в коде инициализации вашего пакета (убедитесь, что ваш пакет загружен до открытия решения) через службу SVsSolutionBuildManager
(приведите к IVsSolutionBuildManager3
и вызовите AdviseUpdateSolutionEvents3
на нем).
- Реализуйте
IVsHierarchyEvents
, чтобы получать уведомления об изменениях проекта, таких как изменение свойств узла (используйте перечисление __VSHPROPID
, чтобы узнать, что есть что), добавление, удаление, аннулирование узлов и т. д. Вызовите AdviseHierarchyEvents
для объекта IVsHierarchy
, переданного в реализацию OnAfterProjectOpen
IVsSolutionEvents3
, чтобы зарегистрировать объект слушателя событий.
person
Cameron
schedule
29.01.2016