【问题标题】:How to cast ComObject to ENVDTE.Project for Unmodeled projects?对于未建模的项目,如何将 ComObject 转换为 ENVDTE.Project?
【发布时间】:2013-06-04 08:47:05
【问题描述】:

我的问题和这个很相似:How to cast ComObject to ENVDTE.Project?

我想处理在 Visual Studio -> 解决方案资源管理器中选择的项目项。如果项目已加载,代码可以正常工作,但我在卸载项目时遇到问题(它们被称为未建模项目 (http://msdn.microsoft.com/en-us/library/hw7ek4f4%28v=vs.80%29.aspx)。

为加载的项目投射选定的项目uiItem.Object is EnvDTE.Project 很好,但是如何投射未建模的项目? 没有“UnmodeledProject”类,并且强制转换 uiItem.Object is ProjectItem 不起作用。

这是我的代码:

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
            {  ...

【问题讨论】:

    标签: c# visual-studio-addins envdte


    【解决方案1】:

    由于我没有找到解决这种情况的方法,所以我使用了这个技巧:

    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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案2】:

      解决方案资源管理器中所有已加载/已卸载项目的列表将在您的 EnvDTE 应用程序对象中可用。在不使用解决方案资源管理器窗口和 UIHierarchy 的情况下,我得到了项目详细信息。下面的代码 sn-ps 对我来说很好。请查看适合您的天气..

      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
      

      【讨论】:

      • 不,这是我不想走的路。我想识别所选项目的类别,但感谢您的评论。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      相关资源
      最近更新 更多