private bool IsPackageInstalled(Project project, string packageId, NuGetVersion nugetVersion) { if (project == null) { throw new ArgumentNullException("project"); } if (string.IsNullOrEmpty(packageId)) { throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "packageId"); } // We simply use ThreadHelper.JoinableTaskFactory.Run instead of PumpingJTF.Run, unlike, // VsPackageInstaller and VsPackageUninstaller. Because, no powershell scripts get executed // as part of the operations performed below. Powershell scripts need to be executed on the // pipeline execution thread and they might try to access DTE. Doing that under // ThreadHelper.JoinableTaskFactory.Run will consistently result in a hang return(_threadingService.JoinableTaskFactory.Run(async delegate { try { IEnumerable <PackageReference> installedPackageReferences = await GetInstalledPackageReferencesAsync(project); return PackageServiceUtilities.IsPackageInList(installedPackageReferences, packageId, nugetVersion); } catch (Exception exception) { await _telemetryProvider.PostFaultAsync(exception, typeof(VsPackageInstallerServices).FullName); throw; } })); }
/// <summary> /// Internal install method. All installs from the VS API and template wizard end up here. /// </summary> internal async Task InstallInternalAsync( Project project, List <PackageIdentity> packages, ISourceRepositoryProvider repoProvider, VSAPIProjectContext projectContext, bool includePrerelease, bool ignoreDependencies, CancellationToken token) { // Go off the UI thread. This may be called from the UI thread. Only switch to the UI thread where necessary // This method installs multiple packages and can likely take more than a few secs // So, go off the UI thread explicitly to improve responsiveness await TaskScheduler.Default; var gatherCache = new GatherCache(); var sources = repoProvider.GetRepositories().ToList(); // store expanded node state var expandedNodes = await VsHierarchyUtility.GetAllExpandedNodesAsync(); try { var depBehavior = ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior.Lowest; var packageManager = CreatePackageManager(repoProvider); // find the project var nuGetProject = await _solutionManager.GetOrCreateProjectAsync(project, projectContext); var packageManagementFormat = new PackageManagementFormat(_settings); // 1 means PackageReference var preferPackageReference = packageManagementFormat.SelectedPackageManagementFormat == 1; // Check if default package format is set to `PackageReference` and project has no // package installed yet then upgrade it to `PackageReference` based project. if (preferPackageReference && (nuGetProject is MSBuildNuGetProject) && !(await nuGetProject.GetInstalledPackagesAsync(token)).Any() && await NuGetProjectUpgradeUtility.IsNuGetProjectUpgradeableAsync(nuGetProject, project, needsAPackagesConfig: false)) { nuGetProject = await _solutionManager.UpgradeProjectToPackageReferenceAsync(nuGetProject); } // install the package foreach (var package in packages) { var installedPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token); // Check if the package is already installed if (package.Version != null && PackageServiceUtilities.IsPackageInList(installedPackageReferences, package.Id, package.Version)) { continue; } // Perform the install await InstallInternalCoreAsync( packageManager, gatherCache, nuGetProject, package, sources, projectContext, includePrerelease, ignoreDependencies, token); } } finally { // collapse nodes await VsHierarchyUtility.CollapseAllNodesAsync(expandedNodes); } }