Roslyn 和 ProjectId - 不是唯一的(实现 VSIX)

Roslyn and ProjectId - not unique (implementing VSIX)

我正在创建一些 VSIX。 现在,一开始,我使用 Roslyn 进行了一些代码分析,并从解决方案中获取了所有项目:

async Task AnalyzeCode()
{
    foreach (var project in workspace.CurrentSolution.Projects)
        await AnalyzeProject(project);
}


async Task AnalyzeProject(Project project)
    {
        Models.ProjectInfo pi = new Models.ProjectInfo();
        pi.FileName = project.FilePath;
        pi.Name = project.Name;
        pi.Id = project.Id;
        projectsInSolution.Add(pi.Name, pi);

        foreach(var doc in project.Documents)
            await AnalyzeDocument(pi, doc);
    }

等等。如您所见,我正在从 roslyn 的项目 class 中获取 ProjectId。 此 ProjectId class 具有我稍后保存在设置中的 GUID 类型的字段 ID。

现在,当用户在解决方案资源管理器中右键单击项目节点时,我必须检查该选定项目的 ID 是否是保存在设置中的 ID。所以我使用 dte:

获取项目 ID
UIHierarchy solutionExplorer = dte.ToolWindows.SolutionExplorer;
        object[] selectedItems = solutionExplorer.SelectedItems as object[];

        Guid projectGuid;

        if (selectedItems.Length > 0)
        {
            IVsHierarchy hierarchy;
            Project project = (selectedItems[0] as UIHierarchyItem).Object as Project;
            solution.GetProjectOfUniqueName(project.FullName, out hierarchy);

            if(hierarchy != null)                   
                hierarchy.GetGuidProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, out projectGuid);                
        }

但问题是从 IVsHierarchy 读取的 projectGuid 与使用 Roslyn 读取的不同。此外,Roslyn 读取的 ProjectId.Id 在每次应用程序启动时都是不同的。当然,从 IVsHierarchy 读取的项目 guid 总是相同的,所以它必须是真正有效的项目 guid。

所以问题是 - 如何使用 Roslyn 读取真正有效的项目 guid?

ProjectId 中的 GUID 是我们每次加载项目时生成的。这也有点古怪,因为在一个针对多个框架的项目中,每个框架都有一个单独的 Id 和 GUID,即使根据 [=19 的其他部分的定义,它是一个单一的 'project' =].

如果将 Workspace 转换为 VisualStudioWorkspace,则可以使用更多方法。它看起来像我们的 convenient method to just fetch the GUID directly is internal(糟糕!),但您可以调用 VisualStudioWorkspace.GetHierarchy,以这种方式为其提供 Roslyn ProjectId,然后像在第二个代码段中那样调用 GetGuidProperty。

标准警告也适用于无法在后台线程上可靠地调用 GetGuidProperty 而不冒死锁的风险,因此如果您不熟悉线程指南,请小心。我承认从你的问题中不能完全清楚项目 GUID 是否是首先要使用的正确的东西......