【问题标题】:Visual Studio SDK - Handling File Add, Remove, and Rename EventsVisual Studio SDK - 处理文件添加、删除和重命名事件
【发布时间】:2016-01-29 22:32:05
【问题描述】:

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

this question 的答案指出,VS 提供了通过DocumentEvents 接口监听文档事件的基础设施,例如保存、打开和关闭。例如:

Dte.Events.DocumentEvents.DocumentSaved

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

【问题讨论】:

    标签: c# visual-studio visual-studio-extensions visual-studio-sdk


    【解决方案1】:

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

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您提供如此详细的文章。这非常有帮助。我最终使用了您提到的事件和运行文档表事件的组合来处理我需要的所有案例。
    • 感谢您的精彩解释。我想注册一个 IVsHierarchyEvents 来对添加/删除的项目做出反应,就像你描述的那样。但看起来 AdviseUpdateSolutionEvents3 需要一个 IVsUpdateSolutionEvents3,而不是 IVsSolutionEvents3。我们如何注册 IVsSolutionEvents3 的实现?
    • @dybzon 是的,我想我把界面搞混了。编辑了我的答案,希望现在是正确的。谢谢!
    • @Cameron 这正是我在搞砸了一段时间后得到的结果。似乎工作。非常感谢您回来编辑您的答案 - 非常感谢。
    【解决方案2】:

    【讨论】:

    • 嗯,很酷,不知道 ProjectItemsEvents 存在。它真的适用于所有不同的项目系统吗?
    • 感谢您的建议 - 我在发布之前曾尝试使用 ProjectEvents 和 ProjectItemEvents,但不能针对我正在使用的项目类型实施它们。作为旁注,他们的方法和事件都标记为“仅限 Microsoft 内部使用”。在 MSDN 上,所以我不确定使用它们是否是个好主意。
    【解决方案3】:

    我知道这是一篇旧帖子,但对于其他正在寻找快速解决方案的人来说。看看IVsTrackProjectDocuments2 类,它匹配IVsTrackProjectDocumentsEvents2 事件接口。

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

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

    • 添加目录

    • 添加文件

    • 删除目录

    • 删除文件

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

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

    【讨论】:

      猜你喜欢
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 2014-07-09
      • 2018-11-14
      • 1970-01-01
      • 2014-12-17
      相关资源
      最近更新 更多