views:

630

answers:

2

I've got a visual studio addin written by developer who is no longer at the company and have no idea how to debug it. But I want to add a feature so it can recurse into solution folders.

Sounds simple but I'm not sure the api allows testing for this? Well there's got to be a way because AnkhSVN and VisualSVN work fine with Solution Folders.

StackOverflow I'm reaching out for some help on this issue.

Thanks

Notes

-We are using solution folders to hide "Dependency Projects" which are basically a list of project references that we probably don't care about in the particular solution and want to hide by default.

public class Connect : IDTExtensibility2, IDTCommandTarget
{

public void GetProjectLocations(DTE2 dte)
{

UIHierarchy UIH = dte.ToolWindows.SolutionExplorer;

try
{
     UIHierarchyItem UIHItemd = UIH.UIHierarchyItems.Item(1);
}
catch (Exception E)
{
  Debug.Write(E);
}

UIHierarchyItem UIHItem = UIH.UIHierarchyItems.Item(1);//this looks suspect to me

// Iterate through first level nodes.
for (int i = 1; i <= UIHItem.UIHierarchyItems.Count; i++)
{
  Project TempGeneralProjObj = dte.Solution.Item(i);  

  if (TempGeneralProjObj.Kind == PrjKind.prjKindCSharpProject)
  {
  }

}

}

}
+1  A: 

To debug a Visual Studio add-in, load the source code into a copy of visual studio that is not running the add-in. Then, configure the project to start a second copy of visual studio when you "run" the project, that second copy will then run with the first able to breakpoint and debug it.

Make sure you have a batch file (or equivalent) to clean up, so that you can always get back to running VS without the plugin.

Useful resources ...

Bevan
+3  A: 

So far from my tests it appears that solution folders will cast to type Project surprisingly and once that is done the Project.ProjectItems property will hold a list of Projects that may exists underneath that folder. So in short, this is one way to at least get information about how things are structured. The problem however is that each ProjectItem located underneath a solution folder appears to cast find to type ProjectItem but doesn't seem to be able to be cast to a Project.

This is how I'm currently detecting a solution folder in my loop.

if(project.Kind == "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}")
{
    // TODO: Do your thing
}

This has also been frustrating me and I've also noticed a bug in how ActiveReports handles solution folders as well which is related to this same issue.

UPDATE!

Ok so I found the solution but I can't claim it 100% because I found most of it at Macaw's Blog.

So it appears that my original findings were right on however in order to get the actual project type for each ProjectItem under the solution item you need to look under the ProjectItem.SubProject property.

Now Macaw takes a recursive approach to walking the project structure which I think I would also normally recommend however in my case I wanted a single method implementation to simply log out an XML representation of the project for simple research purposes so I ended up using a Stack implementation. For reference you can find my code below which is successfully handling at least one level of solution folders full of projects only and no other specialty solution items.

        XElement rootNode = new XElement("Solution");
        rootNode.Add(new XAttribute("Name", _applicationObject.Solution.FullName));

        Stack<Project> projectStack = 
            new Stack<Project>(_applicationObject.Solution.Projects.Cast<Project>());

        while(projectStack.Count > 0)
        {
            var project = (Project)projectStack.Pop();
            var solutionItemName = "Project";

            if(project.Kind == "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}")
            {
                foreach(ProjectItem innerProject in project.ProjectItems)
                {
                    if(innerProject.SubProject != null)
                    {
                        projectStack.Push(innerProject.SubProject);
                    }
                }
                solutionItemName = "Folder";
            }

            var projectNode = new XElement(
                solutionItemName, 
                new XAttribute("Name", project.Name),
                new XAttribute("Kind", project.Kind)
                );
            rootNode.Add(projectNode);

            foreach(ProjectItem item in project.ProjectItems)
            {
                var itemNode = new XElement("Item", new XAttribute("Name", item.Name));
                projectNode.Add(itemNode);

                if(item.Properties == null)
                {
                    continue;
                }

                foreach(Property property in item.Properties)
                {
                    var propertyNode = new XElement(property.Name, property.Value);
                    itemNode.Add(propertyNode);
                }
            }
        }

By the fact of this post and by apparent bugs in other Add-ins it is apparent that this isn't the most intuitive design but thats what we have to live with.

jpierson