public void RestorePackages(Project project) { const string eventName = nameof(IVsPackageRestorer) + "." + nameof(RestorePackages); using var _ = NuGetETW.ExtensibilityEventSource.StartStopEvent(eventName); try { var solutionDirectory = _solutionManager.SolutionDirectory; var nuGetProjectContext = new EmptyNuGetProjectContext(); // 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 the UI stop responding _threadingService.JoinableTaskFactory.Run(() => _restoreManager.RestoreMissingPackagesInSolutionAsync(solutionDirectory, nuGetProjectContext, NullLogger.Instance, CancellationToken.None)); } catch (Exception exception) { _telemetryProvider.PostFault(exception, typeof(VsPackageRestorer).FullName); } }
/// <summary> /// Installs application package. /// </summary> /// <remarks> /// На текущий момент это вся документация по использованию библиотек Nuget: /// https://daveaglick.com/posts/exploring-the-nuget-v3-libraries-part-1 /// https://daveaglick.com/posts/exploring-the-nuget-v3-libraries-part-2 /// https://daveaglick.com/posts/exploring-the-nuget-v3-libraries-part-3 /// </remarks> /// <returns></returns> public async Task Install(AppInfo appInfo) { var sourceRepository = new SourceRepository(_nugetSettings.PackageSource.Value, _nugetSettings.ResourceProviders); var sourceRepositoryProvider = new SourceRepositoryProvider(_nugetSettings.Configuration.Value, _nugetSettings.ResourceProviders); var project = new FolderNuGetProject(_appSettings.InstallDirectoryPath); var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, _nugetSettings.Configuration.Value, PackagesFolderPath) { PackagesFolderNuGetProject = project }; var resolutionContext = new ResolutionContext(DependencyBehavior.Lowest, true, false, VersionConstraints.None); var emptyNuGetProjectContext = new EmptyNuGetProjectContext(); var sourceRepositories = Array.Empty <SourceRepository>(); await nuGetPackageManager.InstallPackageAsync(project, new PackageIdentity(appInfo.PackageId, NuGetVersion.Parse(appInfo.Version)), resolutionContext, emptyNuGetProjectContext, sourceRepository, sourceRepositories, CancellationToken.None); if (appInfo.HasInstance()) { var directoryName = Path.Combine(_appSettings.InstallDirectoryPath, $"{appInfo.PackageId}.{appInfo.Version}"); var directoryForInstanceName = Path.Combine(_appSettings.InstallDirectoryPath, appInfo.ToString()); var directoryInfo = new DirectoryInfo(directoryName); if (directoryInfo.Exists && !Directory.Exists(directoryForInstanceName)) { directoryInfo.MoveTo(directoryForInstanceName); } } }
/// <summary> /// Uninstall <paramref name="package"/>, while still keeping the downloaded file in the cache. /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="package">Package to uninstall.</param> public async Task UninstallPackage(NugetPackage package, ProgressReport progress) { #if DEBUG var installedPackages = GetPackagesInstalled(new [] { package.Id }); Debug.Assert(installedPackages.FirstOrDefault(p => p.Equals(package)) != null); #endif using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(package.Id, package.Version.ToNuGetVersion()); // Notify that uninstallation started. var installPath = GetInstalledPath(identity.Id, identity.Version.ToPackageVersion()); if (installPath == null) { throw new InvalidOperationException($"Could not find installation path for package {identity}"); } OnPackageUninstalling(this, new PackageOperationEventArgs(new PackageName(package.Id, package.Version), installPath)); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Uninstall, PackageExtractionContext = new PackageExtractionContext(NativeLogger) }; // Simply delete the installed package and its .nupkg installed in it. // Note: this doesn't seem to work because it looks for folder in V2 pattern: <id>.<version> rathern than <id>/<version> //await currentManager.PackagesFolderNuGetProject.DeletePackage(package.Identity, projectContext, CancellationToken.None); await Task.Run(() => FileSystemUtility.DeleteDirectorySafe(installPath, true, projectContext)); if (IsPackageV2(package.Id, package.Version)) { // We also need to clean up global V3 folder (download happen in that folder) var installedPathV3 = InstalledPathResolver.GetPackageDirectory(package.Id, package.Version.ToNuGetVersion()); if (installedPathV3 != null) { await Task.Run(() => FileSystemUtility.DeleteDirectorySafe(installedPathV3, true, projectContext)); } } // Notify that uninstallation completed. OnPackageUninstalled(this, new PackageOperationEventArgs(new PackageName(package.Id, package.Version), installPath)); //currentProgressReport = progress; //try //{ // manager.UninstallPackage(package.IPackage); //} //finally //{ // currentProgressReport = null; //} } finally { currentProgressReport = null; } } }
// TODO: Add IDeleteOnRestartManager, VsPackageInstallerEvents and IVsFrameworkMultiTargeting to constructor public VSNuGetProjectFactory(Func <string> packagesPath) { if (packagesPath == null) { throw new ArgumentNullException("packagesPath"); } _packagesPath = packagesPath; EmptyNuGetProjectContext = new EmptyNuGetProjectContext(); }
/// <summary> /// Uninstall <paramref name="package"/>, while still keeping the downloaded file in the cache. /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="package">Package to uninstall.</param> public async Task UninstallPackage(NugetPackage package, ProgressReport progress) { #if DEBUG var installedPackages = GetPackagesInstalled(new [] { package.Id }); Debug.Assert(installedPackages.FirstOrDefault(p => p.Equals(package)) != null); #endif using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(package.Id, package.Version.ToNuGetVersion()); // Notify that uninstallation started. var installPath = GetInstalledPath(identity.Id, identity.Version.ToPackageVersion()); if (installPath == null) { throw new InvalidOperationException($"Could not find installation path for package {identity}"); } OnPackageUninstalling(this, new PackageOperationEventArgs(new PackageName(package.Id, package.Version), installPath)); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Uninstall, PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger), }; // Simply delete the installed package and its .nupkg installed in it. await Task.Run(() => FileSystemUtility.DeleteDirectorySafe(installPath, true, projectContext)); // Notify that uninstallation completed. OnPackageUninstalled(this, new PackageOperationEventArgs(new PackageName(package.Id, package.Version), installPath)); //currentProgressReport = progress; //try //{ // manager.UninstallPackage(package.IPackage); //} //finally //{ // currentProgressReport = null; //} if (package.Id == "Xenko" && package.Version < new PackageVersion(3, 0, 0, 0)) { UpdateTargetsHelper(); } } finally { currentProgressReport = null; } } }
public void RestorePackages(Project project) { try { var solutionDirectory = _solutionManager.SolutionDirectory; var nuGetProjectContext = new EmptyNuGetProjectContext(); // 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 NuGetUIThreadHelper.JoinableTaskFactory.Run(() => _restoreManager.RestoreMissingPackagesInSolutionAsync(solutionDirectory, nuGetProjectContext, CancellationToken.None)); } catch (Exception ex) { ExceptionHelper.WriteErrorToActivityLog(ex); } }
/// <summary> /// Fetch, if not already downloaded, and install the package represented by /// (<paramref name="packageId"/>, <paramref name="version"/>). /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="packageId">Name of package to install.</param> /// <param name="version">Version of package to install.</param> public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, IEnumerable <string> targetFrameworks, ProgressReport progress) { using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(packageId, version.ToNuGetVersion()); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, true, true, VersionConstraints.None); var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray(); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Install, PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger), }; ActivityCorrelationId.StartNew(); { var installPath = SettingsUtility.GetGlobalPackagesFolder(settings); // In case it's a package without any TFM (i.e. Visual Studio plugin), we still need to specify one if (!targetFrameworks.Any()) { targetFrameworks = new string[] { "net6.0" } } ; // Old version expects to be installed in GamePackages if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0) && oldRootDirectory != null) { installPath = oldRootDirectory; } var projectPath = Path.Combine("StrideLauncher.json"); var spec = new PackageSpec() { Name = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency FilePath = projectPath, Dependencies = new List <LibraryDependency>() { new LibraryDependency { LibraryRange = new LibraryRange(packageId, new VersionRange(version.ToNuGetVersion()), LibraryDependencyTarget.Package), } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.Combine(Path.GetTempPath(), $"StrideLauncher-{packageId}-{version.ToString()}"), OriginalTargetFrameworks = targetFrameworks.ToList(), ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = installPath, Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, }; foreach (var targetFramework in targetFrameworks) { spec.TargetFrameworks.Add(new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse(targetFramework) }); } using (var context = new SourceCacheContext { MaxAge = DateTimeOffset.UtcNow }) { context.IgnoreFailedSources = true; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(spec); dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = context, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = NativeLogger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; foreach (var request in requests) { // Limit concurrency to avoid timeout request.Request.MaxDegreeOfConcurrency = 4; var command = new RestoreCommand(request.Request); // Act var result = await command.ExecuteAsync(); if (!result.Success) { throw new InvalidOperationException($"Could not restore package {packageId}"); } foreach (var install in result.RestoreGraphs.Last().Install) { var package = result.LockFile.Libraries.FirstOrDefault(x => x.Name == install.Library.Name && x.Version == install.Library.Version); if (package != null) { var packagePath = Path.Combine(installPath, package.Path); OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(install.Library.Name, install.Library.Version.ToPackageVersion()), packagePath)); } } } } if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0)) { UpdateTargetsHelper(); } } // Load the recently installed package var installedPackages = GetPackagesInstalled(new[] { packageId }); return(installedPackages.FirstOrDefault(p => p.Version == version)); } finally { currentProgressReport = null; } } }
public async Task <NuGetInstallResult> InstallPackage( string packageId, NuGetVersion version, bool prerelease) { var installPath = Path.Combine(Path.GetTempPath(), "testnuget"); var projectContext = new EmptyNuGetProjectContext { PackageExtractionContext = new PackageExtractionContext() }; var references = new List <string>(); var frameworkReferences = new List <string>(); var projectSystem = new DelegateNuGetProjectSystem(projectContext, (reference, isFrameworkReference) => { if (isFrameworkReference) { frameworkReferences.Add(reference); } else { references.Add(reference); } }); var project = new MSBuildNuGetProject(projectSystem, installPath, installPath); OverrideProject(project); var packageManager = new NuGetPackageManager(_sourceRepositoryProvider, _settings, installPath); var primaryRepositories = _packageSources.Select(_sourceRepositoryProvider.CreateRepository).ToArray(); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, includePrelease: prerelease, includeUnlisted: true, versionConstraints: VersionConstraints.None); if (version == null) { // Find the latest version using NuGetPackageManager version = await NuGetPackageManager.GetLatestVersionAsync( packageId, project, resolutionContext, primaryRepositories, NullLogger.Instance, CancellationToken.None).ConfigureAwait(false); if (version == null) { throw new Exception("Unable to find package"); } } var packageIdentity = new PackageIdentity(packageId, version); await packageManager.InstallPackageAsync( project, packageIdentity, resolutionContext, projectContext, primaryRepositories, Enumerable.Empty <SourceRepository>(), CancellationToken.None).ConfigureAwait(false); return(new NuGetInstallResult(references.AsReadOnly(), frameworkReferences.AsReadOnly())); }
public async Task <NuGetInstallResult> InstallPackage( string packageId, NuGetVersion version, bool prerelease) { _initializationException?.Throw(); var installPath = Path.Combine(Path.GetTempPath(), "dummynuget"); var projectContext = new EmptyNuGetProjectContext { PackageExtractionContext = new PackageExtractionContext(NullLogger.Instance) }; PackageIdentity currentIdentity = null; var references = new List <string>(); var frameworkReferences = new List <string>(); var projectSystem = new DummyNuGetProjectSystem(projectContext, path => references.Add(GetPackagePath(currentIdentity, path)), path => frameworkReferences.Add(path)); var project = new MSBuildNuGetProject(projectSystem, installPath, installPath); // this is a hack to get the identity of the package added in DummyNuGetProjectSystem.AddReference project.PackageInstalling += (sender, args) => currentIdentity = args.Identity; OverrideProject(project); var packageManager = new NuGetPackageManager(_sourceRepositoryProvider, _settings, installPath); var primaryRepositories = _packageSources.Select(_sourceRepositoryProvider.CreateRepository).ToArray(); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, includePrelease: prerelease, includeUnlisted: true, versionConstraints: VersionConstraints.None); if (version == null) { // Find the latest version using NuGetPackageManager var resolvedPackage = await NuGetPackageManager.GetLatestVersionAsync( packageId, project, resolutionContext, primaryRepositories, NullLogger.Instance, CancellationToken.None).ConfigureAwait(false); if (resolvedPackage == null) { throw new Exception("Unable to find package"); } version = resolvedPackage.LatestVersion; } var packageIdentity = new PackageIdentity(packageId, version); await packageManager.InstallPackageAsync( project, packageIdentity, resolutionContext, projectContext, primaryRepositories, Enumerable.Empty <SourceRepository>(), CancellationToken.None).ConfigureAwait(false); return(new NuGetInstallResult(references.AsReadOnly(), frameworkReferences.AsReadOnly())); }
/// <summary> /// Fetch, if not already downloaded, and install the package represented by /// (<paramref name="packageId"/>, <paramref name="version"/>). /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="packageId">Name of package to install.</param> /// <param name="version">Version of package to install.</param> public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, ProgressReport progress) { using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(packageId, version.ToNuGetVersion()); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, true, true, VersionConstraints.None); var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray(); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Install, PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger), }; ActivityCorrelationId.StartNew(); { var installPath = SettingsUtility.GetGlobalPackagesFolder(settings); // Old version expects to be installed in GamePackages if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0) && oldRootDirectory != null) { installPath = oldRootDirectory; } var specPath = Path.Combine("TestProject", "project.json"); var spec = new PackageSpec() { Name = "TestProject", // make sure this package never collides with a dependency FilePath = specPath, Dependencies = new List <LibraryDependency>() { new LibraryDependency { LibraryRange = new LibraryRange(packageId, new VersionRange(version.ToNuGetVersion()), LibraryDependencyTarget.Package), } }, TargetFrameworks = { new TargetFrameworkInformation { FrameworkName = NuGetFramework.Parse("net472"), } }, }; using (var context = new SourceCacheContext()) { context.IgnoreFailedSources = true; var provider = RestoreCommandProviders.Create(installPath, new List <string>(), sourceRepositoryProvider.GetRepositories(), context, new LocalPackageFileCache(), NativeLogger); var request = new RestoreRequest(spec, provider, context, null, NativeLogger) { //RequestedRuntimes = { "win7-d3d11" }, ProjectStyle = ProjectStyle.DotnetCliTool, }; var command = new RestoreCommand(request); // Act var result = await command.ExecuteAsync(); if (!result.Success) { throw new InvalidOperationException($"Could not restore package {packageId}"); } foreach (var install in result.RestoreGraphs.Last().Install) { var package = result.LockFile.Libraries.FirstOrDefault(x => x.Name == install.Library.Name && x.Version == install.Library.Version); if (package != null) { var packagePath = Path.Combine(installPath, package.Path); OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(install.Library.Name, install.Library.Version.ToPackageVersion()), packagePath)); } } } if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0)) { UpdateTargetsHelper(); } } // Load the recently installed package var installedPackages = GetPackagesInstalled(new[] { packageId }); return(installedPackages.FirstOrDefault(p => p.Version == version)); } finally { currentProgressReport = null; } } }
/// <summary> /// Fetch, if not already downloaded, and install the package represented by /// (<paramref name="packageId"/>, <paramref name="version"/>). /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="packageId">Name of package to install.</param> /// <param name="version">Version of package to install.</param> public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, ProgressReport progress) { // Xenko 2.x still installs in GamePackages var currentManager = IsPackageV2(packageId, version) ? managerV2 : manager; using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var identity = new PackageIdentity(packageId, version.ToNuGetVersion()); var resolutionContext = new ResolutionContext( DependencyBehavior.Lowest, true, true, VersionConstraints.None); var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray(); var projectContext = new EmptyNuGetProjectContext() { ActionType = NuGetActionType.Install, PackageExtractionContext = new PackageExtractionContext(NativeLogger), }; ActivityCorrelationId.StartNew(); { // Equivalent to: // await manager.InstallPackageAsync(manager.PackagesFolderNuGetProject, // identity, resolutionContext, projectContext, repositories, // Array.Empty<SourceRepository>(), // This is a list of secondary source respositories, probably empty // CancellationToken.None); using (var sourceCacheContext = new SourceCacheContext()) { var nuGetProject = currentManager.PackagesFolderNuGetProject; var packageIdentity = identity; var nuGetProjectContext = projectContext; var primarySources = repositories; var secondarySources = Array.Empty <SourceRepository>(); var token = CancellationToken.None; var downloadContext = new PackageDownloadContext(sourceCacheContext); // Step-1 : Call PreviewInstallPackageAsync to get all the nuGetProjectActions var nuGetProjectActions = await currentManager.PreviewInstallPackageAsync(nuGetProject, packageIdentity, resolutionContext, nuGetProjectContext, primarySources, secondarySources, token); // Notify that installations started. foreach (var operation in nuGetProjectActions) { if (operation.NuGetProjectActionType == NuGetProjectActionType.Install) { var installPath = GetInstalledPath(operation.PackageIdentity.Id, operation.PackageIdentity.Version.ToPackageVersion()); OnPackageInstalling(this, new PackageOperationEventArgs(new PackageName(operation.PackageIdentity.Id, operation.PackageIdentity.Version.ToPackageVersion()), installPath)); } } NuGetPackageManager.SetDirectInstall(packageIdentity, nuGetProjectContext); // Step-2 : Execute all the nuGetProjectActions if (IsPackageV2(packageId, version)) { await currentManager.ExecuteNuGetProjectActionsAsync( nuGetProject, nuGetProjectActions, nuGetProjectContext, downloadContext, token); } else { // Download and install package in the global cache (can't use NuGetPackageManager anymore since it is designed for V2) foreach (var operation in nuGetProjectActions) { if (operation.NuGetProjectActionType == NuGetProjectActionType.Install) { using (var downloadResult = await PackageDownloader.GetDownloadResourceResultAsync(primarySources, packageIdentity, downloadContext, InstallPath, NativeLogger, token)) { if (downloadResult.Status != DownloadResourceResultStatus.Available) { throw new InvalidOperationException($"Could not download package {packageIdentity}"); } using (var installResult = await GlobalPackagesFolderUtility.AddPackageAsync(packageIdentity, downloadResult.PackageStream, InstallPath, NativeLogger, token)) { if (installResult.Status != DownloadResourceResultStatus.Available) { throw new InvalidOperationException($"Could not install package {packageIdentity}"); } } } } } } NuGetPackageManager.ClearDirectInstall(nuGetProjectContext); // Notify that installations completed. foreach (var operation in nuGetProjectActions) { if (operation.NuGetProjectActionType == NuGetProjectActionType.Install) { var installPath = GetInstalledPath(operation.PackageIdentity.Id, operation.PackageIdentity.Version.ToPackageVersion()); OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(operation.PackageIdentity.Id, operation.PackageIdentity.Version.ToPackageVersion()), installPath)); } } } } // Load the recently installed package var installedPackages = GetPackagesInstalled(new[] { packageId }); return(installedPackages.FirstOrDefault(p => p.Version == version)); } finally { currentProgressReport = null; } } }