private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects, RestoreOperationSource source, DateTimeOffset startTime, double duration) { var sortedProjects = projects.OrderBy( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName)); var projectIds = sortedProjects.Select( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray(); var restoreTelemetryEvent = new RestoreTelemetryEvent( _nuGetProjectContext.OperationId.ToString(), projectIds, source, startTime, _status, _packageCount, _noOpProjectsCount, DateTimeOffset.Now, duration); TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent); var sources = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList(); var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources); TelemetryActivity.EmitTelemetryEvent(sourceEvent); }
private void NuGetPowerShellUsage_SolutionOpenHandler() { lock (_lock) { // Edge case: PMC used without solution load if (!_vsSolutionData.SolutionLoaded && _vsSolutionData.PmcExecuteCommandCount > 0) { // PMC used before any solution is loaded, let's emit what we have for nugetvsinstanceclose event. TelemetryActivity.EmitTelemetryEvent(_vsSolutionData.ToTelemetryEvent()); ClearSolutionData(); } if (_vsSolutionData.LoadedFromPmc) { _vsInstanceData.PmcLoadedSolutionCount++; } if (_vsSolutionData.LoadedFromPmui) { _vsInstanceData.PmuiLoadedSolutionCount++; } _vsInstanceData.SolutionCount = ++_solutionCount; _vsSolutionData.SolutionLoaded = true; } }
private async Task AddVsProjectAdapterToCacheAsync(IVsProjectAdapter vsProjectAdapter) { _projectSystemCache.TryGetProjectNameByShortName(vsProjectAdapter.ProjectName, out var oldProjectName); // Create the NuGet project first. If this throws we bail out and do not change the cache. var nuGetProject = await CreateNuGetProjectAsync(vsProjectAdapter); // Then create the project name from the project. var newProjectName = vsProjectAdapter.ProjectNames; // Finally, try to add the project to the cache. var added = _projectSystemCache.AddProject(newProjectName, vsProjectAdapter, nuGetProject); if (added && nuGetProject != null) { // Emit project specific telemetry as we are adding the project to the cache. // This ensures we do not emit the events over and over while the solution is // open. TelemetryActivity.EmitTelemetryEvent(await VSTelemetryServiceUtility.GetProjectTelemetryEventAsync(nuGetProject)); } if (string.IsNullOrEmpty(DefaultNuGetProjectName) || newProjectName.ShortName.Equals(DefaultNuGetProjectName, StringComparison.OrdinalIgnoreCase)) { DefaultNuGetProjectName = oldProjectName != null ? oldProjectName.CustomUniqueName : newProjectName.ShortName; } }
/// <summary> /// Emits telemetry event once /// </summary> public void EmitIfNeeded() { if (Interlocked.CompareExchange(ref _emittedFlag, 1, 0) == 0) { TelemetryActivity.EmitTelemetryEvent(new TelemetryEvent(EventName)); } }
private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects, bool forceRestore, RestoreOperationSource source, DateTimeOffset startTime, double duration, PackageSourceTelemetry.Totals protocolDiagnosticTotals, IntervalTracker intervalTimingTracker) { var sortedProjects = projects.OrderBy( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName)); var projectIds = sortedProjects.Select( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray(); var restoreTelemetryEvent = new RestoreTelemetryEvent( _nuGetProjectContext.OperationId.ToString(), projectIds, forceRestore, source, startTime, _status, packageCount: _packageCount, noOpProjectsCount: _noOpProjectsCount, upToDateProjectsCount: _upToDateProjectCount, DateTimeOffset.Now, duration, isSolutionLoadRestore: _isSolutionLoadRestore, intervalTimingTracker); TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent); var sources = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList(); var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources, protocolDiagnosticTotals); TelemetryActivity.EmitTelemetryEvent(sourceEvent); }
private void NuGetPowerShellUsage_SolutionCloseHandler() { lock (_lock) { TelemetryActivity.EmitTelemetryEvent(_vsSolutionData.ToTelemetryEvent()); ClearSolutionData(); } }
public async Task UpgradeNuGetProjectAsync(INuGetUI uiService, NuGetProject nuGetProject) { var context = uiService.UIContext; // Restore the project before proceeding var solutionDirectory = context.SolutionManager.SolutionDirectory; await context.PackageRestoreManager.RestoreMissingPackagesInSolutionAsync(solutionDirectory, uiService.ProjectContext, CancellationToken.None); var packagesDependencyInfo = await context.PackageManager.GetInstalledPackagesDependencyInfo(nuGetProject, CancellationToken.None, includeUnresolved : true); var upgradeInformationWindowModel = new NuGetProjectUpgradeWindowModel(nuGetProject, packagesDependencyInfo.ToList()); var result = uiService.ShowNuGetUpgradeWindow(upgradeInformationWindowModel); if (!result) { // raise upgrade telemetry event with Cancelled status var packagesCount = upgradeInformationWindowModel.UpgradeDependencyItems.Count; var upgradeTelemetryEvent = VSTelemetryServiceUtility.GetUpgradeTelemetryEvent( uiService.Projects, NuGetOperationStatus.Cancelled, packagesCount); TelemetryActivity.EmitTelemetryEvent(upgradeTelemetryEvent); return; } var progressDialogData = new ProgressDialogData(Resources.NuGetUpgrade_WaitMessage); string backupPath; using (var progressDialogSession = context.StartModalProgressDialog(Resources.WindowTitle_NuGetMigrator, progressDialogData, uiService)) { backupPath = await PackagesConfigToPackageReferenceMigrator.DoUpgradeAsync( context, uiService, nuGetProject, upgradeInformationWindowModel.UpgradeDependencyItems, upgradeInformationWindowModel.NotFoundPackages, progressDialogSession.Progress, progressDialogSession.UserCancellationToken); } if (!string.IsNullOrEmpty(backupPath)) { var htmlLogFile = GenerateUpgradeReport(nuGetProject, backupPath, upgradeInformationWindowModel); Process process = null; try { process = Process.Start(htmlLogFile); } catch { } } }
protected override void ProcessRecordCore() { var startTime = DateTimeOffset.Now; // start timer for telemetry event TelemetryServiceUtility.StartOrResumeTimer(); // Run Preprocess outside of JTF Preprocess(); NuGetUIThreadHelper.JoinableTaskFactory.Run(async() => { await _lockService.ExecuteNuGetOperationAsync(() => { SubscribeToProgressEvents(); WarnIfParametersAreNotSupported(); if (!_readFromPackagesConfig && !_readFromDirectPackagePath && _nugetVersion == null) { Task.Run(InstallPackageByIdAsync); } else { var identities = GetPackageIdentities(); Task.Run(() => InstallPackagesAsync(identities)); } WaitAndLogPackageActions(); UnsubscribeFromProgressEvents(); return(Task.FromResult(true)); }, Token); }); // stop timer for telemetry event and create action telemetry event instance TelemetryServiceUtility.StopTimer(); var isPackageSourceMappingEnabled = PackageSourceMappingUtility.IsMappingEnabled(ConfigSettings); var actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( OperationId.ToString(), new[] { Project }, NuGetOperationType.Install, OperationSource.PMC, startTime, _status, _packageCount, TelemetryServiceUtility.GetTimerElapsedTimeInSeconds(), isPackageSourceMappingEnabled: isPackageSourceMappingEnabled); // emit telemetry event along with granular level events TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); }
protected override void ProcessRecordCore() { var startTime = DateTimeOffset.Now; // start timer for telemetry event TelemetryServiceUtility.StartOrResumeTimer(); // Run Preprocess outside of JTF Preprocess(); NuGetUIThreadHelper.JoinableTaskFactory.Run(async() => { await _lockService.ExecuteNuGetOperationAsync(() => { SubscribeToProgressEvents(); WarnIfParametersAreNotSupported(); // Update-Package without ID specified if (!_idSpecified) { Task.Run(UpdateOrReinstallAllPackagesAsync); } // Update-Package with Id specified else { Task.Run(UpdateOrReinstallSinglePackageAsync); } WaitAndLogPackageActions(); UnsubscribeFromProgressEvents(); return(Task.FromResult(true)); }, Token); }); // stop timer for telemetry event and create action telemetry event instance TelemetryServiceUtility.StopTimer(); var actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( OperationId.ToString(), new[] { Project }, NuGetOperationType.Update, OperationSource.PMC, startTime, _status, _packageCount, TelemetryServiceUtility.GetTimerElapsedTimeInSeconds()); // emit telemetry event along with granular level events TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); }
private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects, bool forceRestore, RestoreOperationSource source, DateTimeOffset startTime, double duration, PackageSourceTelemetry.Totals protocolDiagnosticTotals, IntervalTracker intervalTimingTracker) { var sortedProjects = projects.OrderBy( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName)); var projectIds = sortedProjects.Select( project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray(); var projectDictionary = sortedProjects .GroupBy(x => x.ProjectStyle) .ToDictionary(x => x.Key, y => y.Count()); var packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(_settings); bool isPackageSourceMappingEnabled = packageSourceMapping?.IsEnabled ?? false; var restoreTelemetryEvent = new RestoreTelemetryEvent( _nuGetProjectContext.OperationId.ToString(), projectIds, forceRestore, source, startTime, _status, packageCount: _packageCount, noOpProjectsCount: _noOpProjectsCount, upToDateProjectsCount: _upToDateProjectCount, unknownProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.Unknown, 0), // appears in DependencyGraphRestoreUtility projectJsonProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.ProjectJson, 0), packageReferenceProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackageReference, 0), legacyPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is LegacyPackageReferenceProject).Count(), cpsPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is CpsPackageReferenceProject).Count(), dotnetCliToolProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.DotnetCliTool, 0), // appears in DependencyGraphRestoreUtility packagesConfigProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackagesConfig, 0), DateTimeOffset.Now, duration, _trackingData, intervalTimingTracker, isPackageSourceMappingEnabled); TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent); var sources = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList(); var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources, protocolDiagnosticTotals); TelemetryActivity.EmitTelemetryEvent(sourceEvent); }
private void NuGetPowerShellUsage_VSInstanseCloseHandler() { lock (_lock) { // Edge case: PMC used without solution load if (!_vsSolutionData.SolutionLoaded && _vsSolutionData.PmcExecuteCommandCount > 0) { // PMC used before any solution is loaded, let's emit what we have for nugetvsinstanceclose event. TelemetryActivity.EmitTelemetryEvent(_vsSolutionData.ToTelemetryEvent()); } // Emit VS Instance telemetry TelemetryActivity.EmitTelemetryEvent(_vsInstanceData.ToTelemetryEvent()); } }
/// <summary> /// Handles Hyperlink controls inside this DetailControl class associated with /// <see cref="PackageManagerControlCommands.OpenExternalLink" /> /// </summary> /// <param name="sender">A Hyperlink control</param> /// <param name="e">Command arguments</param> private void ExecuteOpenExternalLink(object sender, ExecutedRoutedEventArgs e) { var hyperlink = e.OriginalSource as Hyperlink; if (hyperlink != null && hyperlink.NavigateUri != null) { Control.Model.UIController.LaunchExternalLink(hyperlink.NavigateUri); e.Handled = true; if (e.Parameter is not null and HyperlinkType hyperlinkType) { var evt = new HyperlinkClickedTelemetryEvent(hyperlinkType, UIUtility.ToContractsItemFilter(Control.ActiveFilter), Control.Model.IsSolution); TelemetryActivity.EmitTelemetryEvent(evt); } } }
public static void EmitException(string className, string methodName, Exception exception) { if (className == null) { throw new ArgumentNullException(nameof(className)); } if (methodName == null) { throw new ArgumentNullException(nameof(methodName)); } if (exception == null) { throw new ArgumentNullException(nameof(exception)); } TelemetryEvent ToTelemetryEvent(Exception e, string name) { TelemetryEvent te = new TelemetryEvent(name); te["Message"] = e.Message; te["ExceptionType"] = e.GetType().FullName; te["StackTrace"] = e.StackTrace; if (e is AggregateException aggregateException) { var exceptions = aggregateException.InnerExceptions .Select(ie => ToTelemetryEvent(ie, name: null)) .ToList(); te.ComplexData["InnerExceptions"] = exceptions; } else if (e.InnerException != null) { var inner = ToTelemetryEvent(e.InnerException, name: null); te.ComplexData["InnerException"] = inner; } return(te); } TelemetryEvent telemetryEvent = ToTelemetryEvent(exception, $"errors/{className}.{methodName}"); TelemetryActivity.EmitTelemetryEvent(telemetryEvent); }
public void EmitTelemetryEvent(Guid parentId) { var telemetryEvent = new TelemetryEvent(PackagePreFetcherInformation); telemetryEvent["DownloadStartTime"] = _downloadStartTime; telemetryEvent["PackageFetchTime"] = _packageFetchTime; telemetryEvent["TaskReturnTime"] = _taskReturnTime; var packageId = CryptoHashUtility.GenerateUniqueToken(Package.ToString()); telemetryEvent.AddPiiData("PackageId", Package.ToString()); if (parentId != Guid.Empty) { telemetryEvent["ParentId"] = parentId.ToString(); } TelemetryActivity.EmitTelemetryEvent(telemetryEvent); }
protected override void ProcessRecordCore() { var startTime = DateTimeOffset.Now; _packageCount = 1; var stopWatch = Stopwatch.StartNew(); // Run Preprocess outside of JTF Preprocess(); NuGetUIThreadHelper.JoinableTaskFactory.Run(async() => { await _lockService.ExecuteNuGetOperationAsync(() => { SubscribeToProgressEvents(); Task.Run(UninstallPackageAsync); WaitAndLogPackageActions(); UnsubscribeFromProgressEvents(); return(Task.FromResult(true)); }, Token); }); stopWatch.Stop(); var isPackageSourceMappingEnabled = PackageSourceMappingUtility.IsMappingEnabled(ConfigSettings); var actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( OperationId.ToString(), new[] { Project }, NuGetOperationType.Uninstall, OperationSource.PMC, startTime, _status, _packageCount, stopWatch.Elapsed.TotalSeconds, isPackageSourceMappingEnabled: isPackageSourceMappingEnabled); // emit telemetry event along with granular level events TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); }
public void SendTelemetry() { var parentId = _parentId.ToString(); foreach (var kvp in _data) { Data data = kvp.Value; string source = kvp.Key; if (!_sources.TryGetValue(kvp.Key, out PackageSource packageSource)) { packageSource = null; } var telemetry = ToTelemetry(data, source, packageSource, parentId); if (telemetry != null) { TelemetryActivity.EmitTelemetryEvent(telemetry); } } }
public async Task SendTelemetryAsync() { var parentId = _parentId.ToString(); foreach (var kvp in _data) { Data data = kvp.Value; string source = kvp.Key; if (!_sources.TryGetValue(kvp.Key, out SourceRepository sourceRepository)) { // Should not be possible. This is just defensive programming to avoid an exception being thrown in case I'm wrong. sourceRepository = new SourceRepository(new PackageSource(source), Repository.Provider.GetCoreV3()); } var telemetry = await ToTelemetryAsync(data, sourceRepository, parentId, _actionName, _packageSourceMappingConfiguration); if (telemetry != null) { TelemetryActivity.EmitTelemetryEvent(telemetry); } } }
public void Initialize(IConsole console) { NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate { ActiveConsole = console; if (_initialized.HasValue) { if (_initialized.Value && console.ShowDisclaimerHeader) { DisplayDisclaimerAndHelpText(); } } else { try { bool _isPmc = console is IWpfConsole; var result = _runspaceManager.GetRunspace(console, _name); Runspace = result.Item1; _nugetHost = result.Item2; _initialized = true; if (console.ShowDisclaimerHeader) { DisplayDisclaimerAndHelpText(); } UpdateWorkingDirectory(); if (!PowerShellLoaded) { var telemetryEvent = new PowerShellLoadedEvent(isPmc: _isPmc, psVersion: Runspace.PSVersion.ToString()); TelemetryActivity.EmitTelemetryEvent(telemetryEvent); PowerShellLoaded = true; } NuGetPowerShellUsage.RaisePowerShellLoadEvent(isPMC: _isPmc); await ExecuteInitScriptsAsync(); // check if PMC console is actually opened, then only hook to solution load/close events. if (_isPmc) { // Hook up solution events _solutionManager.Value.SolutionOpened += (_, __) => HandleSolutionOpened(); _solutionManager.Value.SolutionClosed += (o, e) => { UpdateWorkingDirectory(); DefaultProject = null; NuGetUIThreadHelper.JoinableTaskFactory.Run(CommandUiUtilities.InvalidateDefaultProjectAsync); }; } _solutionManager.Value.NuGetProjectAdded += (o, e) => UpdateWorkingDirectoryAndAvailableProjects(); _solutionManager.Value.NuGetProjectRenamed += (o, e) => UpdateWorkingDirectoryAndAvailableProjects(); _solutionManager.Value.NuGetProjectUpdated += (o, e) => UpdateWorkingDirectoryAndAvailableProjects(); _solutionManager.Value.NuGetProjectRemoved += (o, e) => { UpdateWorkingDirectoryAndAvailableProjects(); // When the previous default project has been removed, _solutionManager.DefaultNuGetProjectName becomes null if (_solutionManager.Value.DefaultNuGetProjectName == null) { // Change default project to the first one in the collection SetDefaultProjectIndex(0); } }; // Set available private data on Host SetPrivateDataOnHost(false); StartAsyncDefaultProjectUpdate(); } catch (Exception ex) { // catch all exception as we don't want it to crash VS _initialized = false; IsCommandEnabled = false; ReportError(ex); ExceptionHelper.WriteErrorToActivityLog(ex); } } }); }
public async ValueTask <IReadOnlyCollection <IPackageReferenceContextInfo> > GetInstalledPackagesAsync( IReadOnlyCollection <string> projectIds, CancellationToken cancellationToken) { Assumes.NotNullOrEmpty(projectIds); cancellationToken.ThrowIfCancellationRequested(); IReadOnlyList <NuGetProject> projects = await GetProjectsAsync(projectIds, cancellationToken); List <Task <IEnumerable <PackageReference> > > tasks = projects .Select(project => project.GetInstalledPackagesAsync(cancellationToken)) .ToList(); IEnumerable <PackageReference>[] results = await Task.WhenAll(tasks); var installedPackages = new List <PackageReferenceContextInfo>(); GetInstalledPackagesAsyncTelemetryEvent?telemetryEvent = null; for (var i = 0; i < results.Length; ++i) { IEnumerable <PackageReference> packageReferences = results[i]; int totalCount = 0; int nullCount = 0; foreach (PackageReference?packageReference in packageReferences) { ++totalCount; if (packageReference is null) { ++nullCount; continue; } PackageReferenceContextInfo installedPackage = PackageReferenceContextInfo.Create(packageReference); installedPackages.Add(installedPackage); } if (nullCount > 0) { telemetryEvent ??= new GetInstalledPackagesAsyncTelemetryEvent(); NuGetProject project = projects[i]; string projectId = project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId); NuGetProjectType projectType = VSTelemetryServiceUtility.GetProjectType(project); telemetryEvent.AddProject(projectType, projectId, nullCount, totalCount); } } if (telemetryEvent is object) { TelemetryActivity.EmitTelemetryEvent(telemetryEvent); } return(installedPackages); }
public void EmitEvent(TelemetryEvent telemetryEvent) { TelemetryActivity.EmitTelemetryEvent(telemetryEvent); }
public virtual async Task AddReferenceAsync(string referencePath) { if (referencePath == null) { throw new ArgumentNullException(nameof(referencePath)); } var name = Path.GetFileNameWithoutExtension(referencePath); var projectName = string.Empty; var projectFullPath = string.Empty; var assemblyFullPath = string.Empty; var dteProjectFullName = string.Empty; var dteOriginalPath = string.Empty; var resolvedToPackage = false; try { // Perform all DTE operations on the UI thread await NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async delegate { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Read DTE properties from the UI thread projectFullPath = ProjectFullPath; projectName = ProjectName; dteProjectFullName = VsProjectAdapter.FullName; // Get the full path to the reference assemblyFullPath = Path.Combine(projectFullPath, referencePath); // Add a reference to the project dynamic reference; try { // First try the References3.AddFiles API, as that will incur fewer // design-time builds. References3.AddFiles(new[] { assemblyFullPath }, out var referencesArray); var references = (VSLangProj.Reference[])referencesArray; reference = references[0]; } catch (Exception e) { if (e is InvalidCastException) { // We've encountered a project system that doesn't implement References3, or // there's some sort of setup issue such that we can't find the library with // the References3 type. Send a report about this. TelemetryActivity.EmitTelemetryEvent(new TelemetryEvent("References3InvalidCastException")); } // If that didn't work, fall back to References.Add. reference = References.Add(assemblyFullPath); } if (reference != null) { dteOriginalPath = GetReferencePath(reference); // If path != fullPath, we need to set CopyLocal thru msbuild by setting Private // to true. // This happens if the assembly appears in any of the search paths that VS uses to // locate assembly references. // Most commonly, it happens if this assembly is in the GAC or in the output path. // The path may be null or for some project system it can be "". resolvedToPackage = !string.IsNullOrWhiteSpace(dteOriginalPath) && IsSamePath(dteOriginalPath, assemblyFullPath); if (resolvedToPackage) { // Set reference properties (if needed) TrySetCopyLocal(reference); TrySetSpecificVersion(reference); } } }); if (!resolvedToPackage) { // This should be done off the UI thread // Get the msbuild project for this project var buildProject = EnvDTEProjectUtility.AsMSBuildEvaluationProject(dteProjectFullName); if (buildProject != null) { // Get the assembly name of the reference we are trying to add var assemblyName = AssemblyName.GetAssemblyName(assemblyFullPath); // Try to find the item for the assembly name var item = (from assemblyReferenceNode in buildProject.GetAssemblyReferences() where AssemblyNamesMatch(assemblyName, assemblyReferenceNode.Item2) select assemblyReferenceNode.Item1).FirstOrDefault(); if (item != null) { // Add the <HintPath> metadata item as a relative path var projectPath = PathUtility.EnsureTrailingSlash(projectFullPath); var relativePath = PathUtility.GetRelativePath(projectPath, referencePath); item.SetMetadataValue("HintPath", relativePath); // Set <Private> to true item.SetMetadataValue("Private", "True"); FileSystemUtility.MakeWritable(dteProjectFullName); // Change to the UI thread to save NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate { await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Save the project after we've modified it. await SaveProjectAsync(); }); } } else { // The reference cannot be changed by modifying the project file. // This could be a failure, however that could be a breaking // change if there is a non-msbuild project system relying on this // to skip references. // Log a warning to let the user know that their reference may have failed. NuGetProjectContext.Log( ProjectManagement.MessageLevel.Warning, Strings.FailedToAddReference, name); } } }
/// <summary> /// The internal implementation to perform user action. /// </summary> /// <param name="resolveActionsAsync">A function that returns a task that resolves the user /// action into project actions.</param> /// <param name="executeActionsAsync">A function that returns a task that executes /// the project actions.</param> private async Task PerformActionImplAsync( INuGetUI uiService, Func <SourceCacheContext, Task <IReadOnlyList <ResolvedAction> > > resolveActionsAsync, Func <IReadOnlyList <ResolvedAction>, SourceCacheContext, Task> executeActionsAsync, NuGetOperationType operationType, CancellationToken token) { var status = NuGetOperationStatus.Succeeded; var startTime = DateTimeOffset.Now; var packageCount = 0; // Enable granular level telemetry events for nuget ui operation uiService.ProjectContext.OperationId = Guid.NewGuid(); await _lockService.ExecuteNuGetOperationAsync(async() => { try { uiService.BeginOperation(); var acceptedFormat = await CheckPackageManagementFormat(uiService, token); if (!acceptedFormat) { return; } TelemetryServiceUtility.StartOrResumeTimer(); using (var sourceCacheContext = new SourceCacheContext()) { var actions = await resolveActionsAsync(sourceCacheContext); var results = GetPreviewResults(actions); if (operationType == NuGetOperationType.Uninstall) { packageCount = results.SelectMany(result => result.Deleted). Select(package => package.Id).Distinct().Count(); } else { var addCount = results.SelectMany(result => result.Added). Select(package => package.Id).Distinct().Count(); var updateCount = results.SelectMany(result => result.Updated). Select(result => result.New.Id).Distinct().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) { var shouldContinue = uiService.PromptForPreviewAcceptance(results); if (!shouldContinue) { return; } } TelemetryServiceUtility.StartOrResumeTimer(); // Show the license acceptance window. var accepted = await CheckLicenseAcceptanceAsync(uiService, results, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!accepted) { return; } // Warn about the fact that the "dotnet" TFM is deprecated. if (uiService.DisplayDeprecatedFrameworkWindow) { var shouldContinue = ShouldContinueDueToDotnetDeprecation(uiService, actions, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!shouldContinue) { return; } } if (!token.IsCancellationRequested) { // execute the actions await executeActionsAsync(actions, sourceCacheContext); // fires ActionsExecuted event to update the UI uiService.OnActionsExecuted(actions); } } } 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(); var actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( uiService.ProjectContext.OperationId.ToString(), uiService.Projects, operationType, OperationSource.UI, startTime, status, packageCount, duration.TotalSeconds); TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); } }, token); }
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 { } } }
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); }
/// <summary> /// The internal implementation to perform user action. /// </summary> /// <param name="resolveActionsAsync">A function that returns a task that resolves the user /// action into project actions.</param> /// <param name="executeActionsAsync">A function that returns a task that executes /// the project actions.</param> private async Task PerformActionImplAsync( INuGetUI uiService, Func <SourceCacheContext, Task <IReadOnlyList <ResolvedAction> > > resolveActionsAsync, Func <IReadOnlyList <ResolvedAction>, SourceCacheContext, Task> executeActionsAsync, NuGetOperationType operationType, UserAction userAction, CancellationToken token) { var status = NuGetOperationStatus.Succeeded; var startTime = DateTimeOffset.Now; var packageCount = 0; bool continueAfterPreview = true; bool acceptedLicense = true; List <string> removedPackages = null; HashSet <Tuple <string, string> > 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 (var project in uiService.Projects) { var result = await project.GetInstalledPackagesAsync(token); foreach (var package in result) { Tuple <string, string> packageInfo = new Tuple <string, string>(package.PackageIdentity.Id, (package.PackageIdentity.Version == null ? "" : package.PackageIdentity.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(); var acceptedFormat = await CheckPackageManagementFormat(uiService, token); if (!acceptedFormat) { return; } TelemetryServiceUtility.StartOrResumeTimer(); using (var sourceCacheContext = new SourceCacheContext()) { var actions = await resolveActionsAsync(sourceCacheContext); var results = GetPreviewResults(actions); 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) { var shouldContinue = uiService.PromptForPreviewAcceptance(results); if (!shouldContinue) { continueAfterPreview = false; return; } } TelemetryServiceUtility.StartOrResumeTimer(); // Show the license acceptance window. var accepted = await CheckLicenseAcceptanceAsync(uiService, results, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!accepted) { acceptedLicense = false; return; } // Warn about the fact that the "dotnet" TFM is deprecated. if (uiService.DisplayDeprecatedFrameworkWindow) { var shouldContinue = ShouldContinueDueToDotnetDeprecation(uiService, actions, token); TelemetryServiceUtility.StartOrResumeTimer(); if (!shouldContinue) { return; } } if (!token.IsCancellationRequested) { // execute the actions await executeActionsAsync(actions, sourceCacheContext); // fires ActionsExecuted event to update the UI uiService.OnActionsExecuted(actions); } 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 actionTelemetryEvent = VSTelemetryServiceUtility.GetActionTelemetryEvent( uiService.ProjectContext.OperationId.ToString(), uiService.Projects, operationType, OperationSource.UI, startTime, status, packageCount, duration.TotalSeconds); AddUiActionEngineTelemetryProperties(actionTelemetryEvent, continueAfterPreview, acceptedLicense, userAction, existingPackages, addedPackages, removedPackages, updatedPackagesOld, updatedPackagesNew); actionTelemetryEvent["InstalledPackageEnumerationTimeInMilliseconds"] = packageEnumerationTime.ElapsedMilliseconds; TelemetryActivity.EmitTelemetryEvent(actionTelemetryEvent); } }, token); }
public static void OnShutdown() { var telemetryEvent = CreateTelemetryEvent(); TelemetryActivity.EmitTelemetryEvent(telemetryEvent); }