From 8892cc24bc911d65c125093038fca59738347bec Mon Sep 17 00:00:00 2001 From: Jimmy Lewis Date: Mon, 11 Sep 2023 16:32:08 -0700 Subject: [PATCH] Switch away from deprecated NuGet API --- Directory.Packages.props | 3 ++- .../Commands/RestoreOnBuildCommand.cs | 19 +++++++++------- .../LibraryManagerPackage.cs | 22 ++++++++++++++++++- .../Microsoft.Web.LibraryManager.Vsix.csproj | 3 ++- src/LibraryManager.Vsix/Shared/VsHelpers.cs | 12 ++++++++++ 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 91fc71ad..8f1a36e5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -33,7 +33,8 @@ - + + diff --git a/src/LibraryManager.Vsix/Commands/RestoreOnBuildCommand.cs b/src/LibraryManager.Vsix/Commands/RestoreOnBuildCommand.cs index e46c3aaa..92c991ea 100644 --- a/src/LibraryManager.Vsix/Commands/RestoreOnBuildCommand.cs +++ b/src/LibraryManager.Vsix/Commands/RestoreOnBuildCommand.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.ComponentModel.Design; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using EnvDTE; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; @@ -13,7 +15,7 @@ using Microsoft.Web.LibraryManager.Vsix.Contracts; using Microsoft.Web.LibraryManager.Vsix.Shared; using NuGet.VisualStudio; -using Task = System.Threading.Tasks.Task; +using NuGet.VisualStudio.Contracts; namespace Microsoft.Web.LibraryManager.Vsix.Commands { @@ -21,10 +23,10 @@ internal sealed class RestoreOnBuildCommand { private bool _isPackageInstalled; private readonly IComponentModel _componentModel; - private readonly AsyncPackage _package; + private readonly LibraryManagerPackage _package; private readonly IDependenciesFactory _dependenciesFactory; - private RestoreOnBuildCommand(AsyncPackage package, OleMenuCommandService commandService, IDependenciesFactory dependenciesFactory) + private RestoreOnBuildCommand(LibraryManagerPackage package, OleMenuCommandService commandService, IDependenciesFactory dependenciesFactory) { _package = package; _componentModel = VsHelpers.GetService(); @@ -44,7 +46,7 @@ private IServiceProvider ServiceProvider get { return _package; } } - public static void Initialize(AsyncPackage package, OleMenuCommandService commandService, IDependenciesFactory dependenciesFactory) + public static void Initialize(LibraryManagerPackage package, OleMenuCommandService commandService, IDependenciesFactory dependenciesFactory) { Instance = new RestoreOnBuildCommand(package, commandService, dependenciesFactory); } @@ -66,7 +68,7 @@ private async Task BeforeQueryStatusAsync(object sender, EventArgs e) button.Visible = true; button.Enabled = KnownUIContexts.SolutionExistsAndNotBuildingAndNotDebuggingContext.IsActive; - _isPackageInstalled = IsPackageInstalled(item.ContainingProject); + _isPackageInstalled = await IsPackageInstalledAsync(item.ContainingProject); if (_isPackageInstalled) { @@ -165,11 +167,12 @@ private bool UserWantsToInstall() return answer == 6; // 6 = Yes } - private bool IsPackageInstalled(Project project) + private async Task IsPackageInstalledAsync(Project project) { - IVsPackageInstallerServices installerServices = _componentModel.GetService(); + Guid projectGuid = VsHelpers.GetProjectGuid(project); + InstalledPackagesResult installedPackages = await _package.NugetProjectService.GetInstalledPackagesAsync(projectGuid, CancellationToken.None); - return installerServices.IsPackageInstalled(project, Constants.MainNuGetPackageId); + return installedPackages.Packages.Any(p => p.Id == Constants.MainNuGetPackageId); } } } diff --git a/src/LibraryManager.Vsix/LibraryManagerPackage.cs b/src/LibraryManager.Vsix/LibraryManagerPackage.cs index 6c56686d..fbed3df3 100644 --- a/src/LibraryManager.Vsix/LibraryManagerPackage.cs +++ b/src/LibraryManager.Vsix/LibraryManagerPackage.cs @@ -4,13 +4,16 @@ using System; using System.ComponentModel.Composition; using System.ComponentModel.Design; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Threading; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.ServiceBroker; using Microsoft.Web.LibraryManager.Vsix.Commands; using Microsoft.Web.LibraryManager.Vsix.Contracts; using Microsoft.Web.LibraryManager.Vsix.Shared; +using NuGet.VisualStudio.Contracts; using Tasks = System.Threading.Tasks; namespace Microsoft.Web.LibraryManager.Vsix @@ -32,7 +35,7 @@ namespace Microsoft.Web.LibraryManager.Vsix "ActiveProjectFlavor:" + Constants.WebsiteProject, "ActiveProjectCapability:" + Constants.DotNetCoreWebCapability, "HierSingleSelectionName:" + Constants.ConfigFileName + "$" })] - [ProvideUIContextRule(PackageGuids.guidUiContextString, + [ProvideUIContextRule(PackageGuids.guidUiContextString, name: Vsix.Name, expression: "(WAP | WebSite | DotNetCoreWeb )", termNames: new string[] { @@ -53,6 +56,9 @@ internal sealed class LibraryManagerPackage : AsyncPackage [Import] internal IDependenciesFactory DependenciesFactory { get; private set; } + [SuppressMessage("Reliability", "ISB001:Dispose of proxies", Justification = "It is in Dispose()")] + public INuGetProjectService NugetProjectService { get; private set; } + protected override async Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress progress) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); @@ -61,6 +67,13 @@ protected override async Tasks.Task InitializeAsync(CancellationToken cancellati Assumes.Present(componentModel); componentModel.DefaultCompositionService.SatisfyImportsOnce(this); + IAsyncServiceProvider asyncServiceProvider = this; + IBrokeredServiceContainer brokeredServiceContainer = await asyncServiceProvider.GetServiceAsync(); + ServiceHub.Framework.IServiceBroker serviceBroker = brokeredServiceContainer.GetFullAccessServiceBroker(); +#pragma warning disable ISB001 // Dispose of proxies + NugetProjectService = await serviceBroker.GetProxyAsync(NuGetServices.NuGetProjectServiceV1); +#pragma warning restore ISB001 // Dispose of proxies + var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (commandService != null && LibraryCommandService != null) @@ -73,5 +86,12 @@ protected override async Tasks.Task InitializeAsync(CancellationToken cancellati ManageLibrariesCommand.Initialize(this, commandService, LibraryCommandService, DependenciesFactory); } } + + protected override void Dispose(bool disposing) + { + (NugetProjectService as IDisposable)?.Dispose(); + + base.Dispose(disposing); + } } } diff --git a/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj b/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj index db631d92..9e71592a 100644 --- a/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj +++ b/src/LibraryManager.Vsix/Microsoft.Web.LibraryManager.Vsix.csproj @@ -184,7 +184,8 @@ - + + diff --git a/src/LibraryManager.Vsix/Shared/VsHelpers.cs b/src/LibraryManager.Vsix/Shared/VsHelpers.cs index c4c9480e..18e6bfab 100644 --- a/src/LibraryManager.Vsix/Shared/VsHelpers.cs +++ b/src/LibraryManager.Vsix/Shared/VsHelpers.cs @@ -545,5 +545,17 @@ private static void DeleteEmptyFolders(HashSet folders) } } } + + public static Guid GetProjectGuid(Project project) + { + string uniqueName = project.UniqueName; + IVsSolution solution = (IVsSolution)Package.GetGlobalService(typeof(SVsSolution)); + solution.GetProjectOfUniqueName(uniqueName, out IVsHierarchy hierarchy); + hierarchy.GetGuidProperty( + (uint)VSConstants.VSITEMID.Root, + (int)__VSHPROPID.VSHPROPID_ProjectIDGuid, + out Guid projectGuid); + return projectGuid; + } } }