14

I am trying to write a add-in for Visual Studio that, among other things, needs to keep track of every file in a Visual Studio solution. I know what events I need to subscribe to (when a Solution is opened, when a file is added/removed/edited in it, the same for projects, etc), but I don't understand how to actually get a list of files from any of it.

I recently installed CodeRush and have been playing with the DXCore framework. I'm very happy with it's approach at plugins, but I still don't see an obvious way to get a list of files in the solution.

So to sum it up: How, via the Visual Studio SDK or DXCore, do I get a reliable list of files in the solution and it's projects?

Dusda
  • 3,347
  • 5
  • 37
  • 58

3 Answers3

18

Thanks, Reed; the article you linked got me far enough to get a proof of concept churned out in a couple minutes.

Since I feel it's related, here is the iteration and recursive means by which I collected the ProjectItems. I did this in DXCore, but the same idea applies to the raw Visual Studio SDK (DXCore is merely a nicer looking wrapper over the SDK). The 'Solution', 'Projects', 'Project', and 'ProjectItem' objects are right there in EnvDTE.

Setting Projects

EnvDTE.Solution solution = CodeRush.ApplicationObject.Solution;
EnvDTE.Projects projects = solution.Projects;

Iterating over the Projects to pull ProjectItems

var projects = myProjects.GetEnumerator();
while (projects.MoveNext())
{
    var items = ((Project)projects.Current).ProjectItems.GetEnumerator();
    while (items.MoveNext())
    {
        var item = (ProjectItem)items.Current;
        //Recursion to get all ProjectItems
        projectItems.Add(GetFiles(item));
    }
}

Finally, The recursion I do for getting all ProjectItems in the active Solution

ProjectItem GetFiles(ProjectItem item)
{
    //base case
    if (item.ProjectItems == null)
        return item;

    var items = item.ProjectItems.GetEnumerator();
    while (items.MoveNext())
    {
        var currentItem = (ProjectItem)items.Current;
        projectItems.Add(GetFiles(currentItem));
    }

    return item;
}
Dusda
  • 3,347
  • 5
  • 37
  • 58
  • what is the meaning of "CodeRush" here? – greenoldman Mar 12 '11 at 12:19
  • @macias, "CodeRush" here is a reference to the main object for accessing DXCore services. The "CodeRush.ApplicationObject" property returns an EnvDTE object of the DXCore add-in instance. To learn more, follow this link: http://bit.ly/hrweIk – Alex Skorkin Mar 14 '11 at 15:25
  • 1
    BTW, to get a list of solution/project files using the DXCore API, use this line of code: IEnumerable files = CodeRush.Source.ActiveSolution.AllFiles; – Alex Skorkin Mar 14 '11 at 15:31
  • The link in @AlexSkorkin should be http://www.skorkin.com/2010/11/coderush-object-for-accessing-to-dxcore-services/#.Ud_KBUG1Eyg (As not everyone has access to bit.ly at work, :( ) – Stephen Jul 12 '13 at 09:19
  • 2
    The item enumeration here is very naive. For start, it fails to account for nested solution folders, and for files directly under a solution folder (not via a project). – Ofek Shilon Sep 03 '13 at 13:13
  • What is "projectItems"? – Evgeni Nabokov Apr 29 '17 at 21:34
4

This is all available easily using DTE in the Visual Studio SDK.

You can get a list of projects in a solution using the Projects interface.

You can get a list of items in a project using the ProjectItem interface.

For more information, I'd recommend reading up on Controlling Projects and Solutions.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 17
    -1, No, it's not available easily, this answer is just the result of a quick google search. Even though the project interface provides an enumerable ProjectItems, that only contains the top-level items in the project. Project folders need to be traversed and only the files selected. Multiple filenames are also possible for items which further complicates this. – Tamás Szelei Jun 23 '15 at 14:18
  • What is DTE? Please explain acronyms. – user4951 May 04 '23 at 15:35
1

See EnvDTE : Getting all projects (the SolutionFolder PITA)

This solution works brilliantly to get all of the projects in the solution, even if the projects are in subfolders.

Be sure to read the comments below the code, as it points out an essential fix, use this to grab DTE2 instead of the original code, or else it doesn't get the correct instance of Visual Studio:

DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;

(the code was updated to include above fix)

Community
  • 1
  • 1
Contango
  • 76,540
  • 58
  • 260
  • 305