Open AngryShaDoW opened 2 years ago
The Visual Studio API doesn't provide access to NuGet package references, but they can be accessed using NuGet libraries. The NuGet.VisualStudio.Contracts package provides an INuGetProjectService
interface that allows you to get the packages installed in a project. I don't think there's much documentation on how to use those services, but you may be able to find some examples by searching for that interface on GitHub.
I am using the NuGet.ProjectModel package to enumerate package references here: https://github.com/ErikEJ/EFCorePowerTools/blob/master/src/GUI/Shared/Extensions/ProjectExtensions.cs#L138
The Visual Studio API doesn't provide access to NuGet package references, but they can be accessed using NuGet libraries. The NuGet.VisualStudio.Contracts package provides an
INuGetProjectService
interface that allows you to get the packages installed in a project. I don't think there's much documentation on how to use those services, but you may be able to find some examples by searching for that interface on GitHub.
Thanks for the tip. Small example of INuGetProjectService usage:
public static async Task<IEnumerable<NuGetInstalledPackage>> GetInstalledPackagesAsync(this Community.VisualStudio.Toolkit.Project project)
{
var solution = await Community.VisualStudio.Toolkit.VS.GetServiceAsync<SVsSolution, IVsSolution>();
project.GetItemInfo(out var hierarchy, out _, out _);
if (hierarchy == null)
return new NuGetInstalledPackage[0];
int result = solution.GetGuidOfProject(hierarchy, out var projectGuid);
if (result != VSConstants.S_OK)
throw new Exception($"Error calling {nameof(IVsSolution)}.{nameof(IVsSolution.GetGuidOfProject)}: {result}");
var serviceBrokerContainer = await Community.VisualStudio.Toolkit.VS.GetServiceAsync<SVsBrokeredServiceContainer, IBrokeredServiceContainer>();
var serviceBroker = serviceBrokerContainer.GetFullAccessServiceBroker();
var projectService = await serviceBroker.GetProxyAsync<INuGetProjectService>(NuGetServices.NuGetProjectServiceV1);
using (projectService as IDisposable)
{
var packagesResult = await projectService.GetInstalledPackagesAsync(projectGuid, CancellationToken.None);
if (packagesResult.Status != InstalledPackageResultStatus.Successful)
throw new Exception($"Unexpected result from GetInstalledPackagesAsync: {packagesResult.Status}");
var packs = packagesResult.Packages
.Where(p => p.DirectDependency).ToArray();
return packs;
}
}
Question about nuggets is resolved by code above. Do you think it is worth adding simplified methods for working with nuggets to the toolkit, by analogy with references?
With SDK style projects IVsReferenceManagerUser.GetProviderContexts() have not return IVsAssemblyReferenceProviderContext, that's why no any assembly reference have returned at project.References.
Not all SDK style projects, if set <TargetFramework>net48</TargetFramework>
then IVsAssemblyReferenceProviderContext
is present, if <TargetFramework>netstandard2.0</TargetFramework>
then it not exist.
And one more related problem: If assembly reference does not resolved (for example wrong path to assembly) it does not exist at IVsAssemblyReferenceProviderContext.References
.
The IBrokeredService
stuff is VS 2022 only, right?
2019 and 2022, I think.
At #180 have been added reference management functionality. But it work's only for project references and shared projects (with hack inside).
With SDK style projects IVsReferenceManagerUser.GetProviderContexts() have not return IVsAssemblyReferenceProviderContext, that's why no any assembly reference have returned at project.References.
With SDK style project and old style projects no any context to get nugget reference (PackageReference) - no any nugget reference have returned at project.References. Not sure that is such reference context type is exist.