Visual Studio SDK — обработка событий добавления, удаления и переименования файлов

Я работаю над расширением Visual Studio, которое должно прослушивать события, когда пользователь добавляет, удаляет или переименовывает файлы в текущем решении.

В ответе на этот вопрос отмечается, что VS предоставляет инфраструктуру для прослушивания документа события, такие как сохранение, открытие и закрытие через DocumentEvents интерфейс. Например:

Dte.Events.DocumentEvents.DocumentSaved

Существуют ли подобные события, которые позволили бы мне слушать, как пользователь добавляет/удаляет/переименовывает документы?


person Jay Harris    schedule 29.01.2016    source источник


Ответы (3)


Во-первых, не используйте 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
comment
Спасибо за такую ​​подробную запись. Это было невероятно полезно. В итоге я использовал комбинацию упомянутых вами событий и событий Running Document Table для обработки всех необходимых мне случаев. - person Jay Harris; 31.01.2016

Вы можете подписаться на EnvDTE.ProjectsEvents, EnvDTE.ProjectItemsEvents или IVsHierarchyEvents.

person Jakub Bielawa    schedule 29.01.2016
comment
Хм, круто, не знал, что ProjectItemsEvents существует. Действительно ли это работает со всеми различными системами проектов? - person Cameron; 30.01.2016
comment
Спасибо за предложение - я пытался использовать ProjectEvents и ProjectItemEvents перед публикацией, но они не должны быть реализованы для типа проекта, с которым я работаю. В качестве примечания, все их методы и события помечены как только для внутреннего использования Microsoft. на MSDN, поэтому я не уверен, стоит ли их использовать. - person Jay Harris; 31.01.2016

Я знаю, что это старый пост, но для всех, кто ищет быстрое решение. Взгляните на IVsTrackProjectDocuments2 и соответствует IVsTrackProjectDocumentsEvents2 интерфейс события.

Вы будете получать уведомления обо всех элементах проекта (Не элементах решения!), включая Solution Items, которые соответствуют следующим действиям:

  • Переименовать каталоги
  • Переименовать файлы

  • Добавить каталоги

  • Добавить файлы

  • Удалить каталоги

  • Удалить файлы

  • SccStatusChanged (я предполагаю, что он сработает после изменения состояния системы управления версиями файла.)

Они будут содержать массив измененных элементов, их новое состояние и проекты, в которых произошли обновления. Кроме того, вы получите массив VS*FLAGS, содержащий дополнительную информацию о текущей операции.

person Twenty    schedule 27.02.2020