-1

In a Visual Studio extension I need to iterate through all the projects in the loaded solution and find all Dependencies (both NuGet packages as well as assemblies). The following code works fine for old non-SDK style projects but not for the new SDK-style projects.

var dte = ApplicationObject; // DTE object
if (dte == null || dte.Solution == null || !dte.Solution.IsOpen)
{
    return;
}

foreach (Project project in dte.Solution.Projects)
{
    var vsProj = project.Object as VSProject;
    if (vsProj == null || vsProj.References == null)
    {
        // Project not loaded
        continue;
    }

    foreach (Reference reference in vsProj.References)
    {
        if (reference.SourceProject != null 
            || reference.Type != prjReferenceType.prjReferenceTypeAssembly)
        {
            // Skip over non assembly references
            continue;
        }

        // reference.Name contains the reference name
    }
}

In the new SDK-style projects "references" is now called Dependencies but there is no such property on VSProject. So what is the way to get this for SDK-style projects?

Santosh
  • 660
  • 7
  • 13
  • Hi, I tried it in VS2017 and VS2019, the code above works to recognize the nuget packages and references in .net core or .net standard projects. – LoLance Sep 23 '19 at 10:50
  • Any update for this issue? Can you share more details(vs version, project type, framework, the wrong behavior you get) to help reproduce the issue you met :) – LoLance Sep 24 '19 at 08:39
  • 1
    @LanceLi-MSFT Sorry for not getting back earlier. Using the above code I get an empty list in `vsProj.References` when it's run on the new SDK-style project (targetting .netcoreapp2.1). I am using VS2019. Note that the above code gets invoked in the event `IVsSolutionEvents.OnAfterOpenSolution`. – Santosh Sep 26 '19 at 05:02

2 Answers2

1

So what is the way to get this for SDK-style projects?

I'm afraid the answer is negative. This could be one issue related to VS2019 SDK and new SDK project system.

And this issue occurs specifically in IVsSolutionEvents.OnAfterOpenSolutionevent. I tried to invoke similar code in OnQueryCloseSolution event or in a Command Item's click event but it all works well for same solution with one .net core applications in it.

I think it could be one issue cause the solution and project are not null(I output the xx.sln and xx.csproj), but it just can't get reference.Name from vsProj.References. And it works when close solution, but get empty list when open solution.For now, I've found no valid workaround which makes it work.

Issue reported to DC, if anyone's interested in it, you can track the issue here.

LoLance
  • 25,666
  • 1
  • 39
  • 73
  • Thanks for the confirmation that it doesn't work and for reporting the issue. I guess there can't be a better answer than this at this point so I will accept this as the answer. – Santosh Sep 30 '19 at 09:58
  • @Santosh Thanks, and you can track the issue by the link in DC, sorry for the inconvenience :) – LoLance Sep 30 '19 at 09:59
0

The VS2019 project is a .net core 3.1 library project and the following code while the solution is open. is in fact retrieving the path location of a reference stored in the nuget location:

C:\Users\xxxxx\.nuget\packages\subsonic.core.dal\4.2.1\lib\netstandard2.1\SubSonic.Core.DataAccessLayer.dll

public string ResolveAssemblyReference(string assemblyReference)
{
    ThreadHelper.ThrowIfNotOnUIThread();

    string path = EngineHost.ResolveAssemblyReference(assemblyReference);

    if (path.Equals(assemblyReference, StringComparison.Ordinal) &&
        !foundAssembly.IsMatch(path))
    {   // failed to find the assembly, could it be referenced via a project reference?
        if (GetService(typeof(DTE)) is DTE dTE)
        {
            foreach (Project project in dTE.Solution.Projects)
            {
                if (project.Object is VSProject vsProject)
                {
                    path = ResolveAssemblyReferenceByProject(assemblyReference, vsProject.References);
                }
                else if (project.Object is VsWebSite.VSWebSite vsWebSite)
                {
                    path = ResolveAssemblyReferenceByProject(assemblyReference, vsWebSite.References);
                }
            }
        }

        if (!foundAssembly.IsMatch(path))
        {
            LogError(false, SubSonicCoreErrors.FileNotFound, -1, -1, $"{assemblyReference}.dll");
        }
    }

    return path;
}

private string ResolveAssemblyReferenceByProject(string assemblyReference, References references)
{
    foreach (Reference reference in references)
    {
        if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
        {   // found the reference
            return reference.Path;
        }
    }

    return assemblyReference;
}

private string ResolveAssemblyReferenceByProject(string assemblyReference, VsWebSite.AssemblyReferences references)
{
    foreach (VsWebSite.AssemblyReference reference in references)
    {
        if (reference.Name.Equals(assemblyReference, StringComparison.OrdinalIgnoreCase))
        {   // found the reference
            return reference.FullPath;
        }
    }

    return assemblyReference;
}
Matt Ke
  • 3,599
  • 12
  • 30
  • 49