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

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

这个问题的答案指出,VS提供了用于通过DocumentEvents接口监听文档事件(如保存,打开和关闭)的基础结构。 例如:

Dte.Events.DocumentEvents.DocumentSaved 

是否有类似的事件可以让我听取用户添加/删除/重命名文档?

首先,如果你能提供帮助,请不要使用DTE。 这是一个非常不完整,摇摇欲坠的抽象,覆盖在极其复杂的界面上。 话虽如此,我承认有时它非常方便,因为如果没有它(稀有)或者备用代码将会很长(不太罕见),那么等价物就无法完成。

这里有两个概念混为一谈。 第一个是运行文档表(RDT)。 RDT表示所有打开的文件(包括打开的.sln和项目文件)。 您可以订阅RDT事件以获得有关正在打开,关闭,重命名等文件的通知。但这些事件仅适用于打开文件!

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

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

重命名可能是最难检测到的。 每个项目系统都以不同方式实施 在某些项目系统中,重命名将自身显示为节点删除,然后是节点添加,没有可靠的方法来识别它是由于重命名。

总而言之,没有什么是看起来那么简单,特别是涉及到项目系统(Visual Studio中可扩展性最差的部分之一)。 您最终可能会得到特定于一个或少数项目系统的代码,但不会普遍使用。 (毕竟,并非所有项目都代表文件层次结构!那些仍然有文件夹,特殊参考节点等不是文件。)

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

  • 实现IVsSolutionEvents3以通知正在加载/卸载的项目(并且IVsSolutionEvents4将被通知重命名项目本身)。 在包初始化代码中将该对象注册为侦听器(确保在打开解决方案之前加载包),通过SVsSolutionBuildManager服务(转换为IVsSolutionBuildManager3并在其上调用AdviseUpdateSolutionEvents3 )。
  • 实现IVsHierarchyEvents以通知项目更改,例如节点属性更改(使用__VSHPROPID枚举以找出哪个),添加,删除,无效等节点。调用传递给IVsSolutionEvents3OnAfterProjectOpen实现的IVsHierarchy对象上的IVsHierarchy注册事件监听器对象。

您可以订阅EnvDTE.ProjectsEvents , EnvDTE.ProjectItemsEvents或IVsHierarchyEvents 。