private async Task ExecuteInitScriptsAsync() { // Fix for Bug 1426 Disallow ExecuteInitScripts from being executed concurrently by multiple threads. using (await _initScriptsLock.EnterAsync()) { if (!_solutionManager.IsSolutionOpen) { return; } Debug.Assert(_settings != null); if (_settings == null) { return; } var latestRestore = _latestRestore; var latestSolutionDirectory = _solutionManager.SolutionDirectory; if (ShouldNoOpDueToRestore(latestRestore) && ShouldNoOpDueToSolutionDirectory(latestSolutionDirectory)) { _currentRestore = latestRestore; _currentSolutionDirectory = latestSolutionDirectory; return; } // make sure all projects are loaded before start to execute init scripts. Since // projects might not be loaded when DPL is enabled. _solutionManager.EnsureSolutionIsLoaded(); if (!_solutionManager.IsSolutionFullyLoaded) { return; } // invoke init.ps1 files in the order of package dependency. // if A -> B, we invoke B's init.ps1 before A's. var projects = _solutionManager.GetNuGetProjects().ToList(); var packageManager = new NuGetPackageManager( _sourceRepositoryProvider, _settings, _solutionManager, _deleteOnRestartManager); var packagesByFramework = new Dictionary <NuGetFramework, HashSet <PackageIdentity> >(); var sortedGlobalPackages = new List <PackageIdentity>(); // Sort projects by type foreach (var project in projects) { // Skip project K projects. if (project is ProjectKNuGetProjectBase) { continue; } var buildIntegratedProject = project as BuildIntegratedNuGetProject; if (buildIntegratedProject != null) { var packages = await BuildIntegratedProjectUtility .GetOrderedProjectPackageDependencies(buildIntegratedProject); sortedGlobalPackages.AddRange(packages); } else { // Read packages.config var installedRefs = await project.GetInstalledPackagesAsync(CancellationToken.None); if (installedRefs?.Any() == true) { // Index packages.config references by target framework since this affects dependencies NuGetFramework targetFramework; if (!project.TryGetMetadata(NuGetProjectMetadataKeys.TargetFramework, out targetFramework)) { targetFramework = NuGetFramework.AnyFramework; } HashSet <PackageIdentity> fwPackages; if (!packagesByFramework.TryGetValue(targetFramework, out fwPackages)) { fwPackages = new HashSet <PackageIdentity>(); packagesByFramework.Add(targetFramework, fwPackages); } fwPackages.UnionWith(installedRefs.Select(reference => reference.PackageIdentity)); } } } // Each id/version should only be executed once var finishedPackages = new HashSet <PackageIdentity>(); // Packages.config projects if (packagesByFramework.Count > 0) { await ExecuteInitPs1ForPackagesConfig( packageManager, packagesByFramework, finishedPackages); } // build integrated projects if (sortedGlobalPackages.Count > 0) { ExecuteInitPs1ForBuildIntegrated( sortedGlobalPackages, finishedPackages); } // We are done executing scripts, so record the restore and solution directory that we executed for. // This aids the no-op logic above. _currentRestore = latestRestore; _currentSolutionDirectory = latestSolutionDirectory; } }