public static async Task<bool> RestoreMissingPackages(NuGetPackageManager nuGetPackageManager, IEnumerable<PackageReference> packageReferences, INuGetProjectContext nuGetProjectContext, CancellationToken token, EventHandler<PackageRestoredEventArgs> packageRestoredEvent = null, IEnumerable<SourceRepository> sourceRepositories = null) { if(nuGetPackageManager == null) { throw new ArgumentNullException("nuGetPackageManager"); } if(packageReferences == null) { throw new ArgumentNullException("packageReferences"); } if(nuGetProjectContext == null) { throw new ArgumentNullException("nuGetProjectContext"); } if (!packageReferences.Any()) return false; var hashSetOfMissingPackageReferences = new HashSet<PackageReference>(packageReferences, new PackageReferenceComparer()); // Before starting to restore package, set the nuGetProjectContext such that satellite files are not copied yet // Satellite files will be copied as a post operation. This helps restore packages in parallel // and not have to determine if the package is a satellite package beforehand if(nuGetProjectContext.PackageExtractionContext == null) { nuGetProjectContext.PackageExtractionContext = new PackageExtractionContext(); } nuGetProjectContext.PackageExtractionContext.CopySatelliteFiles = false; token.ThrowIfCancellationRequested(); // TODO: Update this to use the locked version bool[] results = await Task.WhenAll(hashSetOfMissingPackageReferences.Select(uniqueMissingPackage => RestorePackageAsync(nuGetPackageManager, uniqueMissingPackage.PackageIdentity, nuGetProjectContext, packageRestoredEvent, sourceRepositories, token))); token.ThrowIfCancellationRequested(); bool[] satelliteFileResults = await Task.WhenAll(hashSetOfMissingPackageReferences.Select(uniqueMissingPackage => nuGetPackageManager.CopySatelliteFilesAsync(uniqueMissingPackage.PackageIdentity, nuGetProjectContext, token))); return results.Any() || satelliteFileResults.Any(); }