예제 #1
0
        private async Task PerformActionAsync(
            INuGetUI uiService,
            UserAction userAction,
            NuGetOperationType operationType,
            ResolveActionsAsync resolveActionsAsync,
            CancellationToken cancellationToken)
        {
            IServiceBroker serviceBroker = uiService.UIContext.ServiceBroker;

            using (INuGetProjectManagerService projectManagerService = await serviceBroker.GetProxyAsync <INuGetProjectManagerService>(
                       NuGetServices.ProjectManagerService,
                       cancellationToken: cancellationToken))
            {
                Assumes.NotNull(projectManagerService);

                await projectManagerService.BeginOperationAsync(cancellationToken);

                try
                {
                    await PerformActionImplAsync(
                        serviceBroker,
                        projectManagerService,
                        uiService,
                        resolveActionsAsync,
                        operationType,
                        userAction,
                        cancellationToken);
                }
                finally
                {
                    await projectManagerService.EndOperationAsync(cancellationToken);
                }
            }
        }
예제 #2
0
 public async ValueTask <IReadOnlyCollection <IPackageReferenceContextInfo> > GetInstalledPackagesAsync(CancellationToken cancellationToken)
 {
     using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(cancellationToken))
     {
         return(await projectManager.GetInstalledPackagesAsync(new string[] { ProjectId }, cancellationToken));
     }
 }
예제 #3
0
 public static async ValueTask <IProjectContextInfo> CreateAsync(string projectId, CancellationToken cancellationToken)
 {
     using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(cancellationToken))
     {
         return(await projectManager.GetProjectAsync(projectId, cancellationToken));
     }
 }
예제 #4
0
 public static async Task <IProjectContextInfo> CreateAsync(IServiceBroker serviceBroker, string projectId, CancellationToken cancellationToken)
 {
     using (INuGetProjectManagerService projectManager = await serviceBroker.GetProxyAsync <INuGetProjectManagerService>(
                NuGetServices.ProjectManagerService,
                CancellationToken.None))
     {
         return(await projectManager.GetProjectAsync(projectId, cancellationToken));
     }
 }
예제 #5
0
        public async ValueTask <IProjectMetadataContextInfo> GetMetadataAsync(CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(cancellationToken))
            {
                return(await projectManager.GetMetadataAsync(ProjectId, cancellationToken));
            }
        }
예제 #6
0
        public async ValueTask <(bool, string?)> TryGetInstalledPackageFilePathAsync(
            PackageIdentity packageIdentity,
            CancellationToken cancellationToken)
        {
            Assumes.NotNull(packageIdentity);

            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(cancellationToken))
            {
                return(await projectManager.TryGetInstalledPackageFilePathAsync(ProjectId, packageIdentity, cancellationToken));
            }
        }
        public static async ValueTask <IProjectMetadataContextInfo> GetMetadataAsync(
            this IProjectContextInfo projectContextInfo,
            IServiceBroker serviceBroker,
            CancellationToken cancellationToken)
        {
            Assumes.NotNull(projectContextInfo);
            Assumes.NotNull(serviceBroker);

            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(serviceBroker, cancellationToken))
            {
                return(await projectManager.GetMetadataAsync(projectContextInfo.ProjectId, cancellationToken));
            }
        }
        public static async ValueTask <IReadOnlyCollection <NuGetFramework> > GetTargetFrameworksAsync(
            this IProjectContextInfo projectContextInfo,
            IServiceBroker serviceBroker,
            CancellationToken cancellationToken)
        {
            Assumes.NotNull(projectContextInfo);
            Assumes.NotNull(serviceBroker);

            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(serviceBroker, cancellationToken))
            {
                return(await projectManager.GetTargetFrameworksAsync(new string[] { projectContextInfo.ProjectId }, cancellationToken));
            }
        }
        public static async ValueTask <IInstalledAndTransitivePackages> GetInstalledAndTransitivePackagesAsync(
            this IProjectContextInfo projectContextInfo,
            IServiceBroker serviceBroker,
            CancellationToken cancellationToken)
        {
            Assumes.NotNull(projectContextInfo);
            Assumes.NotNull(serviceBroker);

            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(serviceBroker, cancellationToken))
            {
                return(await projectManager.GetInstalledAndTransitivePackagesAsync(new string[] { projectContextInfo.ProjectId }, cancellationToken));
            }
        }
        public static async ValueTask <(bool, string?)> TryGetInstalledPackageFilePathAsync(
            this IProjectContextInfo projectContextInfo,
            IServiceBroker serviceBroker,
            PackageIdentity packageIdentity,
            CancellationToken cancellationToken)
        {
            Assumes.NotNull(projectContextInfo);
            Assumes.NotNull(serviceBroker);
            Assumes.NotNull(packageIdentity);

            cancellationToken.ThrowIfCancellationRequested();

            using (INuGetProjectManagerService projectManager = await GetProjectManagerAsync(serviceBroker, cancellationToken))
            {
                return(await projectManager.TryGetInstalledPackageFilePathAsync(
                           projectContextInfo.ProjectId,
                           packageIdentity,
                           cancellationToken));
            }
        }
        public static async ValueTask <IReadOnlyCollection <string> > GetPackageFoldersAsync(
            this IProjectContextInfo projectContextInfo,
            IServiceBroker serviceBroker,
            CancellationToken cancellationToken)
        {
            if (projectContextInfo == null)
            {
                throw new ArgumentNullException(nameof(projectContextInfo));
            }
            if (serviceBroker == null)
            {
                throw new ArgumentNullException(nameof(serviceBroker));
            }

            cancellationToken.ThrowIfCancellationRequested();

            using INuGetProjectManagerService projectManager = await GetProjectManagerAsync(serviceBroker, cancellationToken);

            return(await projectManager.GetPackageFoldersAsync(new string[] { projectContextInfo.ProjectId }, cancellationToken));
        }
예제 #12
0
        /// <summary>
        /// Perform the multi-package update action.
        /// </summary>
        /// <remarks>This needs to be called from a background thread. It may make the UI thread stop responding.</remarks>
        public async Task PerformUpdateAsync(
            INuGetUI uiService,
            List <PackageIdentity> packagesToUpdate,
            CancellationToken cancellationToken)
        {
            IServiceBroker serviceBroker = uiService.UIContext.ServiceBroker;

            using (INuGetProjectManagerService projectManagerService = await serviceBroker.GetProxyAsync <INuGetProjectManagerService>(
                       NuGetServices.ProjectManagerService,
                       cancellationToken: cancellationToken))
            {
                Assumes.NotNull(projectManagerService);

                await PerformActionAsync(
                    uiService,
                    userAction : null,
                    NuGetOperationType.Update,
                    (projectManagerService) =>
                    ResolveActionsForUpdateAsync(projectManagerService, uiService, packagesToUpdate, cancellationToken),
                    cancellationToken);
            }
        }
예제 #13
0
        /// <summary>
        /// Calculates the list of actions needed to perform packages updates.
        /// </summary>
        private async Task <IReadOnlyList <ProjectAction> > ResolveActionsForUpdateAsync(
            INuGetProjectManagerService projectManagerService,
            INuGetUI uiService,
            List <PackageIdentity> packagesToUpdate,
            CancellationToken token)
        {
            bool includePrerelease = packagesToUpdate
                                     .Where(package => package.Version.IsPrerelease)
                                     .Any();

            string[] projectIds = uiService.Projects.Select(project => project.ProjectId).ToArray();

            IReadOnlyList <string> packageSourceNames = uiService.ActivePackageSourceMoniker.PackageSourceNames;

            return(await projectManagerService.GetUpdateActionsAsync(
                       projectIds,
                       packagesToUpdate,
                       VersionConstraints.None,
                       includePrerelease,
                       uiService.DependencyBehavior,
                       packageSourceNames,
                       token));
        }
예제 #14
0
        public async Task UpgradeNuGetProjectAsync(INuGetUI uiService, IProjectContextInfo project)
        {
            Assumes.NotNull(uiService);
            Assumes.NotNull(project);

            INuGetUIContext context = uiService.UIContext;
            // Restore the project before proceeding
            string solutionDirectory = await context.SolutionManagerService.GetSolutionDirectoryAsync(CancellationToken.None);

            await context.PackageRestoreManager.RestoreMissingPackagesInSolutionAsync(
                solutionDirectory,
                uiService.ProjectContext,
                new LoggerAdapter(uiService.ProjectContext),
                CancellationToken.None);

            IServiceBroker serviceBroker = context.ServiceBroker;
            NuGetProjectUpgradeWindowModel upgradeInformationWindowModel;

            using (INuGetProjectManagerService projectManager = await serviceBroker.GetProxyAsync <INuGetProjectManagerService>(
                       NuGetServices.ProjectManagerService,
                       CancellationToken.None))
            {
                Assumes.NotNull(projectManager);

                IReadOnlyCollection <PackageDependencyInfo> packagesDependencyInfo = await projectManager.GetInstalledPackagesDependencyInfoAsync(
                    project.ProjectId,
                    includeUnresolved : true,
                    CancellationToken.None);

                upgradeInformationWindowModel = await NuGetProjectUpgradeWindowModel.CreateAsync(
                    serviceBroker,
                    project,
                    packagesDependencyInfo.ToList(),
                    CancellationToken.None);
            }

            var result = uiService.ShowNuGetUpgradeWindow(upgradeInformationWindowModel);

            if (!result)
            {
                // raise upgrade telemetry event with Cancelled status
                var packagesCount = upgradeInformationWindowModel.UpgradeDependencyItems.Count;

                var upgradeTelemetryEvent       = new UpgradeInformationTelemetryEvent();
                IEnumerable <string> projectIds = await ProjectUtility.GetSortedProjectIdsAsync(
                    uiService.UIContext.ServiceBroker,
                    uiService.Projects,
                    CancellationToken.None);

                upgradeTelemetryEvent.SetResult(
                    projectIds,
                    NuGetOperationStatus.Cancelled,
                    packagesCount);

                TelemetryActivity.EmitTelemetryEvent(upgradeTelemetryEvent);

                return;
            }

            var    progressDialogData = new ProgressDialogData(Resources.NuGetUpgrade_WaitMessage);
            string projectName        = await project.GetUniqueNameOrNameAsync(
                uiService.UIContext.ServiceBroker,
                CancellationToken.None);

            string backupPath;

            var windowTitle = string.Format(
                CultureInfo.CurrentCulture,
                Resources.WindowTitle_NuGetMigrator,
                projectName);

            using (IModalProgressDialogSession progressDialogSession = await context.StartModalProgressDialogAsync(windowTitle, progressDialogData, uiService))
            {
                backupPath = await PackagesConfigToPackageReferenceMigrator.DoUpgradeAsync(
                    context,
                    uiService,
                    project,
                    upgradeInformationWindowModel.UpgradeDependencyItems,
                    upgradeInformationWindowModel.NotFoundPackages,
                    progressDialogSession.Progress,
                    progressDialogSession.UserCancellationToken);
            }

            if (!string.IsNullOrEmpty(backupPath))
            {
                string htmlLogFile = GenerateUpgradeReport(projectName, backupPath, upgradeInformationWindowModel);

                Process process = null;
                try
                {
                    process = Process.Start(htmlLogFile);
                }
                catch { }
            }
        }
예제 #15
0
        private async Task PerformActionImplAsync(
            IServiceBroker serviceBroker,
            INuGetProjectManagerService projectManagerService,
            INuGetUI uiService,
            ResolveActionsAsync resolveActionsAsync,
            NuGetOperationType operationType,
            UserAction userAction,
            CancellationToken cancellationToken)
        {
            var status       = NuGetOperationStatus.Succeeded;
            var startTime    = DateTimeOffset.Now;
            var packageCount = 0;

            var continueAfterPreview = true;
            var acceptedLicense      = true;

            List <string> removedPackages  = null;
            var           existingPackages = new HashSet <Tuple <string, string> >();
            List <Tuple <string, string> > addedPackages      = null;
            List <Tuple <string, string> > updatedPackagesOld = null;
            List <Tuple <string, string> > updatedPackagesNew = null;

            // Enable granular level telemetry events for nuget ui operation
            uiService.ProjectContext.OperationId = Guid.NewGuid();

            Stopwatch packageEnumerationTime = new Stopwatch();

            packageEnumerationTime.Start();
            try
            {
                // collect the install state of the existing packages
                foreach (IProjectContextInfo project in uiService.Projects)
                {
                    IEnumerable <IPackageReferenceContextInfo> installedPackages = await project.GetInstalledPackagesAsync(
                        uiService.UIContext.ServiceBroker,
                        cancellationToken);

                    foreach (IPackageReferenceContextInfo package in installedPackages)
                    {
                        Tuple <string, string> packageInfo = new Tuple <string, string>(
                            package.Identity.Id,
                            (package.Identity.Version == null ? "" : package.Identity.Version.ToNormalizedString()));

                        if (!existingPackages.Contains(packageInfo))
                        {
                            existingPackages.Add(packageInfo);
                        }
                    }
                }
            }
            catch (Exception)
            {
                // don't teardown the process if we have a telemetry failure
            }
            packageEnumerationTime.Stop();

            await _lockService.ExecuteNuGetOperationAsync(async() =>
            {
                try
                {
                    uiService.BeginOperation();

                    using (INuGetProjectUpgraderService projectUpgrader = await serviceBroker.GetProxyAsync <INuGetProjectUpgraderService>(
                               NuGetServices.ProjectUpgraderService,
                               cancellationToken))
                    {
                        bool isAcceptedFormat = await CheckPackageManagementFormatAsync(projectUpgrader, uiService, cancellationToken);
                        if (!isAcceptedFormat)
                        {
                            return;
                        }
                    }

                    TelemetryServiceUtility.StartOrResumeTimer();

                    IReadOnlyList <ProjectAction> actions = await resolveActionsAsync(projectManagerService);
                    IReadOnlyList <PreviewResult> results = await GetPreviewResultsAsync(projectManagerService, actions, cancellationToken);

                    if (operationType == NuGetOperationType.Uninstall)
                    {
                        // removed packages don't have version info
                        removedPackages = results.SelectMany(result => result.Deleted)
                                          .Select(package => package.Id)
                                          .Distinct()
                                          .ToList();
                        packageCount = removedPackages.Count;
                    }
                    else
                    {
                        // log rich info about added packages
                        addedPackages = results.SelectMany(result => result.Added)
                                        .Select(package => new Tuple <string, string>(package.Id, (package.Version == null ? "" : package.Version.ToNormalizedString())))
                                        .Distinct()
                                        .ToList();
                        var addCount = addedPackages.Count;

                        //updated packages can have an old and a new id.
                        updatedPackagesOld = results.SelectMany(result => result.Updated)
                                             .Select(package => new Tuple <string, string>(package.Old.Id, (package.Old.Version == null ? "" : package.Old.Version.ToNormalizedString())))
                                             .Distinct()
                                             .ToList();
                        updatedPackagesNew = results.SelectMany(result => result.Updated)
                                             .Select(package => new Tuple <string, string>(package.New.Id, (package.New.Version == null ? "" : package.New.Version.ToNormalizedString())))
                                             .Distinct()
                                             .ToList();
                        var updateCount = updatedPackagesNew.Count;

                        // update packages count
                        packageCount = addCount + updateCount;

                        if (updateCount > 0)
                        {
                            // set operation type to update when there are packages being updated
                            operationType = NuGetOperationType.Update;
                        }
                    }

                    TelemetryServiceUtility.StopTimer();

                    // Show the preview window.
                    if (uiService.DisplayPreviewWindow)
                    {
                        bool shouldContinue = uiService.PromptForPreviewAcceptance(results);
                        if (!shouldContinue)
                        {
                            continueAfterPreview = false;
                            return;
                        }
                    }

                    TelemetryServiceUtility.StartOrResumeTimer();

                    // Show the license acceptance window.
                    bool accepted = await CheckLicenseAcceptanceAsync(uiService, results, cancellationToken);

                    TelemetryServiceUtility.StartOrResumeTimer();

                    if (!accepted)
                    {
                        acceptedLicense = false;
                        return;
                    }

                    // Warn about the fact that the "dotnet" TFM is deprecated.
                    if (uiService.DisplayDeprecatedFrameworkWindow)
                    {
                        bool shouldContinue = await ShouldContinueDueToDotnetDeprecationAsync(projectManagerService, uiService, cancellationToken);

                        TelemetryServiceUtility.StartOrResumeTimer();

                        if (!shouldContinue)
                        {
                            return;
                        }
                    }

                    if (!cancellationToken.IsCancellationRequested)
                    {
                        await projectManagerService.ExecuteActionsAsync(
                            actions,
                            cancellationToken);

                        string[] projectIds = actions
                                              .Select(action => action.ProjectId)
                                              .Distinct()
                                              .ToArray();

                        uiService.UIContext.RaiseProjectActionsExecuted(projectIds);
                    }
                    else
                    {
                        status = NuGetOperationStatus.Cancelled;
                    }
                }
                catch (System.Net.Http.HttpRequestException ex)
                {
                    status = NuGetOperationStatus.Failed;
                    if (ex.InnerException != null)
                    {
                        uiService.ShowError(ex.InnerException);
                    }
                    else
                    {
                        uiService.ShowError(ex);
                    }
                }
                catch (Exception ex)
                {
                    status = NuGetOperationStatus.Failed;
                    uiService.ShowError(ex);
                }
                finally
                {
                    TelemetryServiceUtility.StopTimer();

                    var duration = TelemetryServiceUtility.GetTimerElapsedTime();

                    uiService.ProjectContext.Log(MessageLevel.Info,
                                                 string.Format(CultureInfo.CurrentCulture, Resources.Operation_TotalTime, duration));

                    uiService.EndOperation();

                    // don't show "Succeeded" if we actually cancelled...
                    if ((!continueAfterPreview) || (!acceptedLicense))
                    {
                        if (status == NuGetOperationStatus.Succeeded)
                        {
                            status = NuGetOperationStatus.Cancelled;
                        }
                    }

                    var plc = new PackageLoadContext(isSolution: false, uiService.UIContext);
                    IReadOnlyCollection <string> frameworks = await plc.GetSupportedFrameworksAsync();
                    string[] projectIds = (await ProjectUtility.GetSortedProjectIdsAsync(
                                               uiService.UIContext.ServiceBroker,
                                               uiService.Projects,
                                               cancellationToken)).ToArray();

                    var packageSourceMapping           = PackageSourceMapping.GetPackageSourceMapping(uiService.Settings);
                    bool isPackageSourceMappingEnabled = packageSourceMapping?.IsEnabled ?? false;
                    var actionTelemetryEvent           = new VSActionsTelemetryEvent(
                        uiService.ProjectContext.OperationId.ToString(),
                        projectIds,
                        operationType,
                        OperationSource.UI,
                        startTime,
                        status,
                        packageCount,
                        DateTimeOffset.Now,
                        duration.TotalSeconds,
                        isPackageSourceMappingEnabled: isPackageSourceMappingEnabled);

                    var nuGetUI = uiService as NuGetUI;
                    AddUiActionEngineTelemetryProperties(
                        actionTelemetryEvent,
                        continueAfterPreview,
                        acceptedLicense,
                        userAction,
                        nuGetUI?.SelectedIndex,
                        nuGetUI?.RecommendedCount,
                        nuGetUI?.RecommendPackages,
                        nuGetUI?.RecommenderVersion,
                        nuGetUI?.TopLevelVulnerablePackagesCount ?? 0,
                        nuGetUI?.TopLevelVulnerablePackagesMaxSeverities?.ToList() ?? new List <int>(),
                        existingPackages,
                        addedPackages,
                        removedPackages,
                        updatedPackagesOld,
                        updatedPackagesNew,
                        frameworks);

                    actionTelemetryEvent["InstalledPackageEnumerationTimeInMilliseconds"] = packageEnumerationTime.ElapsedMilliseconds;

                    TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent);
                }
            }, cancellationToken);
        }
예제 #16
0
        private async Task <IVsWindowFrame> CreateDocWindowForSolutionAsync()
        {
            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            IVsWindowFrame windowFrame = null;
            var            solution    = await this.GetServiceAsync <IVsSolution>();

            var uiShell = await this.GetServiceAsync <SVsUIShell, IVsUIShell>();

            var windowFlags =
                (uint)_VSRDTFLAGS.RDT_DontAddToMRU |
                (uint)_VSRDTFLAGS.RDT_DontSaveAs;

            // when VSSolutionManager is already initialized, then use the existing APIs to check pre-conditions.
            if (!await SolutionManager.Value.IsSolutionAvailableAsync())
            {
                throw new InvalidOperationException(Resources.SolutionIsNotSaved);
            }

            IServiceBroker serviceBroker = await ServiceBrokerProvider.Value.GetAsync();

            IReadOnlyCollection <IProjectContextInfo> projectContexts;

            using (INuGetProjectManagerService projectManagerService = await serviceBroker.GetProxyAsync <INuGetProjectManagerService>(
                       NuGetServices.ProjectManagerService))
            {
                Assumes.NotNull(projectManagerService);
                projectContexts = await projectManagerService.GetProjectsAsync(CancellationToken.None);

                if (projectContexts.Count == 0)
                {
                    MessageHelper.ShowWarningMessage(Resources.NoSupportedProjectsInSolution, Resources.ErrorDialogBoxTitle);
                    return(null);
                }
            }

            INuGetUI uiController = await UIFactory.Value.CreateAsync(serviceBroker, projectContexts.ToArray());

            var solutionName = (string)_dte.Solution.Properties.Item("Name").Value;

            // This model takes ownership of --- and Dispose() responsibility for --- the INuGetUI instance.
            var model = new PackageManagerModel(
                uiController,
                isSolution: true,
                editorFactoryGuid: GuidList.guidNuGetEditorType)
            {
                SolutionName = solutionName
            };

            PackageManagerControl control = await PackageManagerControl.CreateAsync(model, OutputConsoleLogger.Value);

            var windowPane     = new PackageManagerWindowPane(control);
            var guidEditorType = GuidList.guidNuGetEditorType;
            var guidCommandUI  = Guid.Empty;
            var caption        = Resx.Label_SolutionNuGetWindowCaption;
            var documentName   = await SolutionManager.Value.GetSolutionFilePathAsync();

            var ppunkDocView = IntPtr.Zero;
            var ppunkDocData = IntPtr.Zero;
            var hr           = 0;

            try
            {
                ppunkDocView = Marshal.GetIUnknownForObject(windowPane);
                ppunkDocData = Marshal.GetIUnknownForObject(model);
                hr           = uiShell.CreateDocumentWindow(
                    windowFlags,
                    documentName,
                    (IVsUIHierarchy)solution,
                    (uint)VSConstants.VSITEMID.Root,
                    ppunkDocView,
                    ppunkDocData,
                    ref guidEditorType,
                    null,
                    ref guidCommandUI,
                    null,
                    caption,
                    string.Empty,
                    null,
                    out windowFrame);

                if (windowFrame != null)
                {
                    WindowFrameHelper.AddF1HelpKeyword(windowFrame, keywordValue: F1KeywordValuePmUI);
                    WindowFrameHelper.DisableWindowAutoReopen(windowFrame);
                }
            }
            finally
            {
                if (ppunkDocView != IntPtr.Zero)
                {
                    Marshal.Release(ppunkDocData);
                }

                if (ppunkDocData != IntPtr.Zero)
                {
                    Marshal.Release(ppunkDocView);
                }
            }

            ErrorHandler.ThrowOnFailure(hr);
            return(windowFrame);
        }