I've been following MSDN's Hello World guide to developing Visual Studio extensions (this article specifically deals with creating one as a Visual Studio toolbar command).
I am trying to list all projects contained in the current/active solution.
In the auto generated code for the Command template.
I have tried EnvDTE
's Solution
's Projects
property, but it shows zero projects.
There is a ActiveSolutionProjects
property as well, but it also shows an empty array.
How is this achieved ?
P.S.: I tried both DTE and DTE2 interfaces since it is confusing understanding which version to use, from the docs. I get a null service for DTE2, so I am going with DTE.
My Solution Explorer looks like:
Update: Bert Huijben, from gitter/extendvs, suggested the following, found at the VSSDK Extensibility Samples - but this too does not work (returns 0 elements, both within the constructor and within the callback function):
private Hashtable GetLoadedControllableProjectsEnum()
{
Hashtable mapHierarchies = new Hashtable();
IVsSolution sol = (IVsSolution)this.ServiceProvider.GetService(typeof(SVsSolution));
Guid rguidEnumOnlyThisType = new Guid();
IEnumHierarchies ppenum = null;
ErrorHandler.ThrowOnFailure(sol.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref rguidEnumOnlyThisType, out ppenum));
IVsHierarchy[] rgelt = new IVsHierarchy[1];
uint pceltFetched = 0;
while (ppenum.Next(1, rgelt, out pceltFetched) == VSConstants.S_OK &&
pceltFetched == 1)
{
IVsSccProject2 sccProject2 = rgelt[0] as IVsSccProject2;
if (sccProject2 != null)
{
mapHierarchies[rgelt[0]] = true;
}
}
return mapHierarchies;
}
Unfortunately could not find any working solution here, decided to post my own solution:
And if you don't know what references / namespaces to add, you can pick up project with source code from here:
https://github.com/tapika/cppscriptcore/blob/2a73f45474c8b2179774fd4715b8d8e80080f3ae/Tools/vsStart/Program.cs#L478
And check namespaces / references.
Works for me:
Add a field in your package for dte. Get the DTE service. Reference the Solution.
In your constructor:
In your command handler:
I get the correct count from this.
Screenshot (requested)
Code
To get the EnvDTE.Project objects:
Notably recursion is necessary to dig into solution folders.
If you just want the file paths you can do this w/o using DTE:
The following, shamelessly taken from AutoFindReplace, works using VS2015 Community:
All the code lines above pre-exist in the solution within VSPackage.cs except for "var i = dte.Solution.Projects.Count;" which I added locally to VSPackage.cs just after line 44. I then open the solution, hit F5, and within the Experimental Instance I opened JoePublic.Sln and hey presto the count was '2' correctly - Bingo ! Happy days !