in src/NuGet.Clients/NuGet.VisualStudio.Implementation/PreinstalledPackageInstaller.cs [173:317]
internal async Task PerformPackageInstallAsync(
EnvDTE.Project project,
PreinstalledPackageConfiguration configuration,
bool preferPackageReferenceFormat,
Action<string> warningHandler,
Action<string> errorHandler)
{
await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var repositoryPath = configuration.RepositoryPath;
var repositorySource = new Configuration.PackageSource(repositoryPath);
var failedPackageErrors = new List<string>();
// find the project
var defaultProjectContext = new VSAPIProjectContext
{
PackageExtractionContext = new PackageExtractionContext(
PackageSaveMode.Defaultv2,
PackageExtractionBehavior.XmlDocFileSaveMode,
ClientPolicyContext.GetClientPolicy(_settings, NullLogger.Instance),
NullLogger.Instance)
};
var nuGetProject = await _solutionManager.GetOrCreateProjectAsync(project, defaultProjectContext);
if (preferPackageReferenceFormat && await NuGetProjectUpgradeUtility.IsNuGetProjectUpgradeableAsync(nuGetProject, project, needsAPackagesConfig: false))
{
nuGetProject = await _solutionManager.UpgradeProjectToPackageReferenceAsync(nuGetProject);
}
// For BuildIntegratedNuGetProject, nuget will ignore preunzipped configuration.
var buildIntegratedProject = nuGetProject as BuildIntegratedNuGetProject;
var repository = (buildIntegratedProject == null && configuration.IsPreunzipped) ?
_sourceProvider.CreateRepository(repositorySource, FeedType.FileSystemUnzipped) :
_sourceProvider.CreateRepository(repositorySource);
var repoProvider = new PreinstalledRepositoryProvider(errorHandler, _sourceProvider);
repoProvider.AddFromSource(repository);
var packageManager = _installer.CreatePackageManager(repoProvider);
var gatherCache = new GatherCache();
var sources = repoProvider.GetRepositories().ToList();
// store expanded node state
var expandedNodes = await VsHierarchyUtility.GetAllExpandedNodesAsync();
try
{
foreach (var package in configuration.Packages)
{
var packageIdentity = new PackageIdentity(package.Id, package.Version);
// Does the project already have this package installed?
#pragma warning disable CS0618 // Type or member is obsolete
if (_packageServices.IsPackageInstalled(project, package.Id))
{
// If so, is it the right version?
if (!_packageServices.IsPackageInstalledEx(project, package.Id, package.Version.ToNormalizedString()))
#pragma warning restore CS0618 // Type or member is obsolete
{
// No? Raise a warning (likely written to the Output window) and ignore this package.
warningHandler(string.Format(CultureInfo.CurrentCulture, VsResources.PreinstalledPackages_VersionConflict, package.Id, package.Version));
}
// Yes? Just silently ignore this package!
}
else
{
try
{
if (InfoHandler != null)
{
InfoHandler(string.Format(CultureInfo.CurrentCulture, VsResources.PreinstalledPackages_PackageInstallStatus, package.Id, package.Version));
}
// Skip assembly references and disable binding redirections should be done together
var disableBindingRedirects = package.SkipAssemblyReferences;
var projectContext = new VSAPIProjectContext(package.SkipAssemblyReferences, disableBindingRedirects);
var loggerAdapter = new LoggerAdapter(projectContext);
projectContext.PackageExtractionContext = new PackageExtractionContext(
PackageSaveMode.Defaultv2,
PackageExtractionBehavior.XmlDocFileSaveMode,
ClientPolicyContext.GetClientPolicy(_settings, loggerAdapter),
loggerAdapter);
// This runs from the UI thread
await _installer.InstallInternalCoreAsync(
packageManager,
gatherCache,
nuGetProject,
packageIdentity,
sources,
projectContext,
includePrerelease: false,
ignoreDependencies: package.IgnoreDependencies,
token: CancellationToken.None);
}
catch (InvalidOperationException exception)
{
failedPackageErrors.Add(package.Id + "." + package.Version + " : " + exception.Message);
}
catch (AggregateException aggregateEx)
{
var ex = aggregateEx.Flatten().InnerExceptions.FirstOrDefault();
if (ex is InvalidOperationException)
{
failedPackageErrors.Add(package.Id + "." + package.Version + " : " + ex.Message);
}
else
{
throw;
}
}
}
}
if (failedPackageErrors.Any())
{
var errorString = new StringBuilder();
errorString.AppendFormat(CultureInfo.CurrentCulture, VsResources.PreinstalledPackages_FailedToInstallPackage, repositoryPath);
errorString.AppendLine();
errorString.AppendLine();
errorString.Append(string.Join(Environment.NewLine, failedPackageErrors));
errorHandler(errorString.ToString());
}
// RepositorySettings = null in unit tests
if (project.IsWebSite())
{
CreateRefreshFilesInBin(
project,
repositoryPath,
configuration.Packages.Where(p => p.SkipAssemblyReferences));
CopyNativeBinariesToBin(project, repositoryPath, configuration.Packages);
}
}
finally
{
// collapse nodes
await VsHierarchyUtility.CollapseAllNodesAsync(expandedNodes);
}
}