Creating and managing the Solution Items folder from a Visual Studio extension

Visual Studio provides the excellent Solution and Project types for working with the "normal" workflow of solutions containing any number of projects. However, what about the Solution Items folder that gets added when you add a file directly to the solution?

Solution items folder

This is a little trickier to manage, but it is possible!

Retrieving the folder

Fortunately, Visual Studio still includes the Solution Items folder as a real project in the solution! That way, if you know about one of the items in advance, you can use:

var proj = dte.Solution.FindProjectItem(knownFile).ContainingProject;
Or if you don't have any known files:
var proj = dte.Solution.Projects.Cast<Project>().FirstOrDefault(p => p.Name == "Solution Items" || p.Kind == EnvDTE.Constants.vsProjectItemKindSolutionItems);

This should give you the Solution Items folder as a Project that you can manipulate and read as per usual.

Creating the folder

However, if the "project" doesn't exist yet, the above methods will fail. To create the Solution Items project, you will need to cast the Solution into it's equivalent Solution2 object, with a new AddSolutionFolder() method. That is:

Solution2 sol2 = (Solution2)dte.Solution;  
var solItems = sol2.AddSolutionFolder("Solution Items");  
solItems?.AddFileToProject(newFile);  

Final result

Combining these two approaches we can create a simple "get or create" method for the Solution Items folder, perfect for adding build scripts, documentation and bootstrappers to!
An example is below:

internal static Project GetOrCreateSolutionItems(DTE2 dte)  
{
    var solItems = dte.Solution.Projects.Cast<Project>().FirstOrDefault(p => p.Name == "Solution Items" || p.Kind == EnvDTE.Constants.vsProjectItemKindSolutionItems);
    if (solItems == null)
    {
        Solution2 sol2 = (Solution2)dte.Solution;
        solItems = sol2.AddSolutionFolder("Solution Items");
        dte.StatusBar.Text = $"Created Solution Items project for solution {dte.Solution.FullName}";
    }
    return solItems;
}

Comments

comments powered by Disqus