Visual Studio SDK - 处理文件添加、删除和重命名事件

Visual Studio SDK - Handling File Add, Remove, and Rename Events

我正在开发一个 Visual Studio 扩展,当用户在当前解决方案中添加、删除或重命名文件时,它应该监听事件。

this question notes that VS provides infrastructure for listening to document events like saving, opening and closing through the DocumentEvents界面的答案。例如:

Dte.Events.DocumentEvents.DocumentSaved

是否有类似事件可以让我收听用户 adding/removing/renaming 文档?

您可以订阅EnvDTE.ProjectsEvents, EnvDTE.ProjectItemsEvents or IVsHierarchyEvents

首先,如果可以的话,不要使用DTE。这是一个非常不完整、不稳定的抽象,覆盖在一个极其复杂的界面上。话虽如此,我承认有时它非常方便,因为没有它就无法完成等价物(很少见)或者替代代码会很长(不太罕见)。

这里混淆了两个概念。第一个是 运行 文档 Table (RDT)。 RDT 代表所有打开的文件(包括打开的 .sln 和项目文件)。您可以订阅 RDT 事件以在文件打开、关闭、重命名等时收到通知。但这些事件仅针对打开的文件!

第二个概念是项目系统。解决方案资源管理器中加载和显示的每个项目都由该项目类型的项目系统加载。 C++项目、C#项目、F#项目、WIX安装程序项目等都有不同的项目系统。甚至可以有通过扩展实现的自定义项目系统。听起来您想了解项目系统中的事件,而不是(仅)打开文件的事件。所以你的重点是项目系统。然而,由于所有项目系统都有不同的实现,这变得非常棘手。 VS 正在朝着通用项目系统 (CPS) 的方向发展,但还不是 100%,即使是,仍然存在所有遗留扩展等问题

您可以订阅所有项目系统都必须提供的一般“层次结构”事件。例如,他们会告诉您何时添加或删除文件(实际上,当添加或删除层次结构项(节点)时,因为文件和层次结构项之间不一定存在对应关系)。还有一个事件表明整个层次结构已失效 - 一种刷新,您必须丢弃您对项目的所有了解并收集新信息。

重命名可能是最难检测的事情。每个项目系统都以不同的方式实现它。在一些项目系统中,重命名将表现为先删除节点再添加节点,没有可靠的方法来识别它是由于重命名引起的。

总而言之,没有什么事情像看起来那么简单,尤其是涉及到项目系统时(Visual Studio 中可扩展性最低的部分之一)。您最终可能会得到特定于一个或少数项目系统的代码,但不会通用。 (毕竟,并非所有项目甚至都代表文件层次结构!那些代表文件层次结构的项目仍然有文件夹、特殊引用节点等,它们不是文件。)

正确方向的一些具体指示:

  • 实施 IVsSolutionEvents3 以在项目 loaded/unloaded 时收到通知(并且 IVsSolutionEvents4 在项目本身被重命名时收到通知)。通过 SVsSolution 服务(转换为 IVsSolution 并在其上调用 AdviseSolutionEvents)将该对象注册为程序包初始化代码中的侦听器(确保在打开解决方案之前加载程序包) .
  • 实现 IVsHierarchyEvents 以通知项目更改,例如节点属性更改(使用 __VSHPROPID 枚举找出哪个是哪个)、添加、删除、失效的节点等。调用 AdviseHierarchyEventsIVsHierarchy 对象上传递给 IVsSolutionEvents3OnAfterProjectOpen 实现以注册事件侦听器对象。

我知道这是一个旧的 post,但对于正在寻找快速解决方案的其他人来说。看看IVsTrackProjectDocuments2 class and it's matching IVsTrackProjectDocumentsEvents2事件接口。

您将收到所有项目项(不是解决方案项!)的通知,包括 Solution Items,它们符合以下操作:

  • 重命名目录
  • 重命名文件

  • 添加目录

  • 添加文件

  • 删除目录

  • 删除文件

  • SccStatusChanged(我猜,它会在文件的源代码控制状态更改后触发。)

这些将包含一组更改的项目、它们的新状态以及发生更新的项目。此外,您将获得一个 VS*FLAGS 数组,其中包含有关当前操作的更多信息。