Reputation: 2125
I am creating some VSIX. Now, at the start, I do some code analysis using Roslyn and get all the projects from solution:
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);
}
And so on. As you can see, I am getting ProjectId from roslyn's Project class. This ProjectId class has field Id of type GUID that I later save in the settings.
Now, when a user right clicks a project node in solution explorer, I have to check wheter id of this selected project is the one saved in settings. So I get the project Id using dte:
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);
}
But the problem is that the projectGuid read from IVsHierarchy is different that the one read using Roslyn. What't more, the ProjectId.Id read by Roslyn is different on every application start. Of course project guid read from IVsHierarchy is always the same, so it must be the real valid project guid.
So the question is - how should one read the real valid project guid using Roslyn?
Upvotes: 2
Views: 173
Reputation: 19021
The GUID that is in a ProjectId is one we generate each time a project loads. It's also a bit funky because in the case of a project targeting multiple frameworks you're going to have a separate Id and GUID there for each, even though it's a single 'project' by the definition of other parts of Visual Studio.
If you cast your Workspace to VisualStudioWorkspace you have a few more methods at your disposal. It looks like our convenient method to just fetch the GUID directly is internal (oops!) but you can call VisualStudioWorkspace.GetHierarchy, give it the Roslyn ProjectId that way, and then call that GetGuidProperty like you have in your second snippet.
Also standard warnings apply that GetGuidProperty can't be called reliably on a background thread without risking deadlocks, so if you're unfamiliar with threading guidelines there be careful. I admit it's not entirely clear from your question whether the project GUID is the right thing to be using in the first place...
Upvotes: 1