Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm working on a Visual Studio extension that should listen for events when the user adds, removes, or renames files in the current solution.

The answer to this question notes that VS provides infrastructure for listening to document events like saving, opening and closing through the DocumentEvents interface. For example:

Dte.Events.DocumentEvents.DocumentSaved

Are there similar events that would allow me to listen to the user adding/removing/renaming documents?

like image 377
Jay Harris Avatar asked Jan 29 '16 22:01

Jay Harris


3 Answers

First, don't use DTE if you can help it. It's a very incomplete, shaky abstraction papered over an extremely complex interface. Having said that, I admit that sometimes it's super handy because the equivalent either can't be done without it (rare) or the alternate code would be quite long (less rare).

There are two concepts being conflated here. The first is the Running Document Table (RDT). The RDT represents all the open files (including the open .sln and project files). You can subscribe to RDT events to be notified of files being opened, closed, renamed, etc. But these events are for open files only!

The second concept is the project system. Each project loaded and displayed in the solution explorer is loaded by the project system for that project's type. C++ projects, C# projects, F# projects, WIX installer projects, etc. all have different project systems. There can even be custom project systems implemented by extensions. It sounds like you want to know about events in the project system, and not events for (just) open files. So your focus is the project system. However, since all project systems have different implementations, this becomes very tricky. VS is moving towards a common project system (CPS), but it's not 100% there yet, and even when it is there remains the problem of all the legacy extensions, etc.

You can subscribe to general "hierarchy" events which all project systems must furnish. They'll tell you for example when a file is added or removed (really, when a hierarchy item (node) is added or removed, since there's not necessarily a correspondence between files and hierarchy items). There's also an event that says the entire hierarchy has been invalidated -- a sort of refresh where you have to discard everything you know about the project and gather up new info.

Rename is probably the hardest thing to detect. Every project system implements it differently. In some project systems, a rename will present itself as a node deletion followed by a node addition, with no solid way to identify that it was due to a rename.

To sum up, nothing is as simple as it seems, particularly when it comes to project systems (one of the least extensible parts of Visual Studio). You'll likely end up with code that is specific to one or a handful of project systems, but won't work universally. (After all, not all projects even represent file hierarchies! And those that do still have folders, special reference nodes, etc. that aren't files.)

Some concrete pointers in the right direction:

  • Implement IVsSolutionEvents3 to be notified of a project being loaded/unloaded (and IVsSolutionEvents4 to be notified of a project itself being renamed). Register that object as a listener in your package initialization code (make sure your package is loaded before a solution is opened) via the SVsSolution service (cast to IVsSolution and call AdviseSolutionEvents on it).
  • Implement IVsHierarchyEvents to be notified of project changes like node properties changing (use the __VSHPROPID enum to find out which is which), nodes being added, removed, invalidated, etc. Call AdviseHierarchyEvents on the IVsHierarchy object passed to the IVsSolutionEvents3's OnAfterProjectOpen implementation to register the event listener object.
like image 130
Cameron Avatar answered Nov 18 '22 21:11

Cameron


You can subscribe to the EnvDTE.ProjectsEvents, EnvDTE.ProjectItemsEvents or IVsHierarchyEvents.

like image 21
Jakub Bielawa Avatar answered Nov 18 '22 20:11

Jakub Bielawa


I know this is an old post by now, but for anyone else, who is searching for a fast solution. Take a look at the IVsTrackProjectDocuments2 class and it's matching IVsTrackProjectDocumentsEvents2 event interface.

You will receive notifications for all project items (Not solution items!), including Solution Items, which match the following actions:

  • Rename Directories
  • Rename Files

  • Add Directories

  • Add Files

  • Remove Directories

  • Remove Files

  • SccStatusChanged (I am guessing, that it will fire after a file's source-control state changed.)

These will contain an array of the changed items, their new state and the projects in which updates occurred. Additionally you will get a VS*FLAGS array, which contains more information about the current operation.

like image 31
Twenty Avatar answered Nov 18 '22 22:11

Twenty