Question

My question is very similar to this one: How to cast ComObject to ENVDTE.Project?

I want to process the Project items selected in Visual Studio -> Solution Explorer. If project is loaded the code works fine but I have troubles for unloaded projects (they are called Unmodeled projects (http://msdn.microsoft.com/en-us/library/hw7ek4f4%28v=vs.80%29.aspx).

Casting selected item for loaded projects uiItem.Object is EnvDTE.Project is fine, but how to cast Unmodeled projects? There is no 'UnmodeledProject' class and casting uiItem.Object is ProjectItem does not work.

This is my code:

Window solutionExplorer = mApplicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
if(solutionExplorer != null)
{
    UIHierarchy uiHierarchy = (UIHierarchy)solutionExplorer.Object;
    if (uiHierarchy != null)
    {
        object[] selectedItems = (object[])uiHierarchy.SelectedItems;
        foreach (UIHierarchyItem uiItem in selectedItems)
        {                              
            // Valid project
            if (uiItem.Object is EnvDTE.Project)
            {
                EnvDTE.Project project = uiItem.Object as EnvDTE.Project;
                if (project.FullName.Contains(".vdproj") || project.Kind == "{54435603-DBB4-11D2-8724-00A0C9A8B90C}")
                {

                }
            }
            else if (uiItem.Object is ProjectItem)
            {
              // This is never jumped...
            }
            else
            {  ...
Was it helpful?

Solution

As I did not find a solution for this situation I used this trick:

string pathToVdProject = null;
try
{
    Window solutionExplorer = mApplicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
    if (solutionExplorer != null)
    {
        UIHierarchy uiHierarchy = (UIHierarchy)solutionExplorer.Object;
        if (uiHierarchy != null)
        {
            object[] selectedItems = (object[])uiHierarchy.SelectedItems;
            foreach (UIHierarchyItem uiItem in selectedItems)
            {
                // Valid project
                if (uiItem.Object is EnvDTE.Project)
                {
                    EnvDTE.Project project = uiItem.Object as EnvDTE.Project;
                    if (project.FullName.Contains(".vdproj") || project.UniqueName.Contains(".vdproj")
                        || (String.Compare(project.Kind, ProjectsGuids.guidVdSetupProject, true) == 0))                                    
                    {
                        // Valid Project has property FullName which is full path to .vdproj file
                        pathToVdProject = project.FullName;
                        break;
                    }
                }
                else if (uiItem.Object is ProjectItem)
                {
                    // This never happens...
                }
                else
                {
                    // This is a little tricky: Unmodeled Projects cannot be casted to EnvDTE.Project http://msdn.microsoft.com/en-us/library/hw7ek4f4%28v=vs.80%29.aspx 
                    Solution2 solution = (Solution2)mApplicationObject.Solution;

                    // So get all projects in solution (including unmodeled) and try to find a match by name
                    foreach (Project project in solution.Projects)
                    {
                        if (project.Kind == EnvDTE.Constants.vsProjectKindUnmodeled)
                        {
                            // Unmodeled project found (Normal projects are recognized in 'uiItem.Object is EnvDTE.Project'
                            if (project.Name.Contains(uiItem.Name))
                            {
                                // This is 'Project' for selected item
                                if (project.Name.Contains(".vdproj") || project.UniqueName.Contains(".vdproj"))
                                {
                                    // Unmodeled projects does not offer property FullName and UniqueName does NOT contain full path to file!
                                    FileInfo fileInfo = new FileInfo(solution.FullName);

                                    // Create full path from solution (.sln) path and project relative path
                                    pathToVdProject = fileInfo.DirectoryName + "\\" + project.UniqueName;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

OTHER TIPS

List of all loaded/Unloaded projects inside the solution explorer will be available in your EnvDTE application object. Without using solution Explorer window and UIHierarchy i got the project details. Below code snippets working fine for me. Please check out weather it will fit for you..

For Each item As EnvDTE.Project In mApplicationObject.Solution.Projects
     If item.Globals Is Nothing AndAlso item.Object Is Nothing Then
        Console.WriteLine(item.Name + "  is currently unloaded!")
     End If
Next
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top