public string GetProjectOutputPath(string name) { DTE dte = (DTE)_serviceProvider.GetService(typeof(DTE)); Project project = FindProjectByName(dte, name); if (project != null) { string fullPath = project.Properties.Item("FullPath").Value.ToString(); string relativeOutputPath = project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString(); string outputPath = Path.Combine(fullPath, relativeOutputPath); return(outputPath); } else { GeneralUtils.ShowMessage("Project " + name + ": output path cannot be found", OLEMSGICON.OLEMSGICON_CRITICAL); return(null); } }
public static bool IsInDebugMode() { var solution = _serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution; if (solution == null) { GeneralUtils.ShowMessage("Failed to get Solution service", OLEMSGICON.OLEMSGICON_CRITICAL); return(false); } IEnumHierarchies enumerator = null; Guid guid = Guid.Empty; solution.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref guid, out enumerator); IVsHierarchy[] hierarchy = new IVsHierarchy[1] { null }; uint fetched = 0; try { for (enumerator.Reset(); enumerator.Next(1, hierarchy, out fetched) == VSConstants.S_OK && fetched == 1; /*nothing*/) { // Verify that this is a project node and not a folder IVsProject project = (IVsProject)hierarchy[0]; string path; int hr = project.GetMkDocument((uint)VSConstants.VSITEMID.Root, out path); if (hr == VSConstants.S_OK) { if (IsInDebugMode(project)) { return(true); } } } } catch (Exception) { GeneralUtils.ShowMessage("Failed to load projects info", OLEMSGICON.OLEMSGICON_CRITICAL); return(false); } return(false); }
public static OperationContext LoadNuGetPackages(bool preRelease) { DTE dte = (DTE)_serviceLocator.GetService(typeof(DTE)); Properties props = dte.get_Properties("NuGet Tool", "General"); Setting setting; try { setting = props.Item(nameof(Setting)).Value as Setting; if (setting == null) { GeneralUtils.ShowMessage("Packages sources are not defined. Use Tools->Options->NuGet.Extension to define the sources", OLEMSGICON.OLEMSGICON_WARNING); return(null); } } #region Exception Handling catch (Exception ex) { System.Diagnostics.Trace.WriteLine($"Setting not found {ex}"); GeneralUtils.ShowMessage("Packages sources are not defined. Use Tools->Options->NuGet.Extension to define the sources", OLEMSGICON.OLEMSGICON_WARNING); return(null); } #endregion // Exception Handling try { var context = new OperationContext(_serviceLocator, preRelease, setting); if (!string.IsNullOrEmpty(context.Errors)) { GeneralUtils.ShowMessage(context.Errors, OLEMSGICON.OLEMSGICON_CRITICAL); return(null); } return(context); } catch (Exception ex) { GeneralUtils.ShowMessage("Failed to Create context: " + ex.Message, OLEMSGICON.OLEMSGICON_CRITICAL); return(null); } }
private static async void Rollback( OperationContext context) { // Recover the old packages for (int i = 0; i < context.PackagesUpdatedSoFar.Count; i++) { NuGetPackageInfo p = context.PackagesUpdatedSoFar[i]; GeneralUtils.ReportStatus($"Rollback: {p.Name}"); string errorMsg = await RollbackPackage(p, context); if (errorMsg != null) { string msg = $@"Failed to recover package {p.Id}. Error: {errorMsg}. {context.RecoveredPackages.Count} NuGet packages have been recovered so far. Choose one of the following actions: Abort: to stop the process (you can repeat the process after fixing the problem). Ignore: to continue recovering the other packages Retry: to try again (from current stage)."; DialogResult option = MessageBox.Show(msg, "Rollback", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); switch (option) { case DialogResult.Abort: return; case DialogResult.Retry: i--; continue; case DialogResult.Ignore: continue; } } } Directory.Delete(context.ArchiveSession); GeneralUtils.ShowMessage($"{context.RecoveredPackages.Count} NuGet packages have been restored"); }
/// <summary> /// Finds the path of the package . /// </summary> /// <param name="packageName">Name of the package.</param> /// <returns></returns> private string FindPackagePath( string packageName) { string packagePath = ""; foreach (string packageSource in PackagesSources) { string path = Path.Combine(packageSource, packageName); if (File.Exists(path)) { if (packagePath == "") { packagePath = packageSource; } else { GeneralUtils.ShowMessage($"Package {packageName} exists in more than one repository. The tool will update only the package in {packagePath}"); } } } return(packagePath); }
private static void SwitchToDebugMode(OperationContext context) { using (GeneralUtils.StartAnimation()) using (var progress = GeneralUtils.StartProgressProgress("To Project Reference", context.Projects.LoadedProjects.Length)) { foreach (ProjectInfo project in context.Projects.LoadedProjects) { try { progress.Increment(); GeneralUtils.ReportStatus($"Switching [{project.Name}]"); SwitchProjectToDebug(project, context); } catch (Exception ex) { GeneralUtils.ShowMessage("Failed to convert project: " + project.Name + ", Error message: " + ex.Message, OLEMSGICON.OLEMSGICON_CRITICAL); } } } context.Projects.ReOpenSolution(); GeneralUtils.ShowMessage("Conversion to debug mode finished successfully."); }
public /*async*/ Task <bool> BuildProject(ProjectInfo project) { DTE dte = (DTE)_serviceProvider.GetService(typeof(DTE)); SolutionBuild solutionBuild = dte.Solution.SolutionBuild; string solutionConfiguration = solutionBuild.ActiveConfiguration.Name; GeneralUtils.ReportStatus($"Build: {project.Name}"); // TODO: 2017-01 Bnaya, Use the async version solutionBuild.BuildProject(solutionConfiguration, project.FullName, true); //await TRD.Tasks.Task.Factory.StartNew(() => // solutionBuild.BuildProject(solutionConfiguration, project.FullName, true), // TaskCreationOptions.LongRunning); bool compiledOK = (solutionBuild.LastBuildInfo == 0); if (!compiledOK && System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break(); } return(TRD.Tasks.Task.FromResult(compiledOK)); }
private static TPL.Task RecoverOldVersionFromArchive( NuGetPackageInfo packageInfo, OperationContext context) { GeneralUtils.ReportStatus($"Recover old version from archive"); return(TPL.Task.Factory.StartNew(() => { string sourcePackagePath = Path.Combine(context.ArchiveSession, packageInfo.PackageFileName); string targetPackagePath = Path.Combine(packageInfo.RepositoryPath, packageInfo.PackageFileName); if (File.Exists(sourcePackagePath)) { File.Move(sourcePackagePath, targetPackagePath); } // Delete the new version from the repository string newPackagePath = Path.Combine(packageInfo.RepositoryPath, packageInfo.NewPackageName); if (File.Exists(newPackagePath)) { File.Delete(newPackagePath); } }, TPL.TaskCreationOptions.LongRunning)); }
private void RevertBackProjectFileToNuGet(ProjectInfo project, OperationContext context) { string newText = ""; string textWithoutHashKey = ""; string origHash = null; // Read the hash code using (StreamReader reader = new StreamReader(project.ProjectFile)) { // Remove all the project references and add the original NuGet references while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.IndexOf("<!--DebugMode") != -1) { // read the hash code int hashStartPos = line.IndexOf(" ") + 1; int hashEndPos = line.IndexOf("-->"); origHash = line.Substring(hashStartPos, hashEndPos - hashStartPos); } else { textWithoutHashKey += line + Environment.NewLine; } } } using (StreamReader reader = new StreamReader(project.ProjectFile)) { // Remove all the project references and add the original NuGet references while (!reader.EndOfStream) { string line = reader.ReadLine(); // Skip the debug mode comment line if (line.IndexOf("<!--DebugMode") != -1) { continue; } if (line.IndexOf("<!--NuGetTool") != -1) { int idx = line.IndexOf("<!--NuGetTool"); string uncommentedLine = line.Substring(idx + 13); newText += uncommentedLine + Environment.NewLine; // Read until the end of the comment line = reader.ReadLine(); while (line.IndexOf("</Reference>") == -1) { newText += line + Environment.NewLine; line = reader.ReadLine(); } // Remove the end of the comment int endOfCommentPos = line.IndexOf("-->"); uncommentedLine = line.Substring(0, endOfCommentPos); newText += uncommentedLine + Environment.NewLine; // Remove the project reference line = reader.ReadLine(); while (line.IndexOf("</ProjectReference>") == -1) { line = reader.ReadLine(); } } else { newText += line + Environment.NewLine; } } } // If the file was checked out first time by the tool, and has not changed // outside the tool, then undo the check out when switching back to NuGet mode if (!String.IsNullOrEmpty(origHash)) { File.WriteAllText(project.ProjectFile, textWithoutHashKey); string newHash = GeneralUtils.ComputeHash(project.ProjectFile); File.WriteAllText(project.ProjectFile, newText); if (origHash == newHash) { TFSUtilities.UndoCheckOut(project.ProjectFile, context.TfsServerUri); } } else { File.WriteAllText(project.ProjectFile, newText); } }
private static void UpdateProjectFile( ProjectInfo project, OperationContext context) { string newText = ""; bool hasFilePendingChanges = TFSUtilities.HasFilePendingChanges(project.ProjectFile, context.TfsServerUri); using (StreamReader reader = new StreamReader(project.ProjectFile)) { // Comment out all NuGet references to projects in the solution // and add project references instead of them while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.IndexOf("<Reference ") != -1) { // Extract the package od int packageIdStartPos = line.IndexOf("\""); int packageIdEndPos = line.IndexOf(",", packageIdStartPos + 1); // Some of the packages are without version number (typically system packages) if (packageIdEndPos == -1) { packageIdEndPos = line.IndexOf("\"", packageIdStartPos + 1); } string packageName = line.Substring(packageIdStartPos + 1, packageIdEndPos - packageIdStartPos - 1).Trim(); ProjectInfo dependencyProject = context.Projects.LoadedProjects.FirstOrDefault(p => p.AssemblyName == packageName); if (dependencyProject != null) { newText += "<!--NuGetTool" + line + Environment.NewLine; line = reader.ReadLine(); // Read until the end of the reference to close the comment while (line.IndexOf("</Reference>") == -1) { newText += line + Environment.NewLine; line = reader.ReadLine(); } newText += line + "-->" + Environment.NewLine; // Add project reference instead of the Nuget reference string projectRef = BuildProjectReference(dependencyProject); newText += projectRef + Environment.NewLine; } else { newText += line + Environment.NewLine; } } else { newText += line + Environment.NewLine; } } } File.WriteAllText(project.ProjectFile, newText); // Compute hash for the file (so we can check if it has changed when switching back to NuGet) string hash64 = null; if (!hasFilePendingChanges) { hash64 = GeneralUtils.ComputeHash(project.ProjectFile); } newText += $"<!--DebugMode {hash64}-->"; File.WriteAllText(project.ProjectFile, newText.ToString()); }
private static void RevertBackPackageConfigToNuGet(ProjectInfo project, OperationContext context) { string packagesConfigFile = Path.Combine(project.Directory, "packages.config"); if (File.Exists(packagesConfigFile)) { string textWithoutHashKey = ""; string newText = ""; string origHash = null; using (StreamReader reader = new StreamReader(packagesConfigFile)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.IndexOf("<!--DebugMode") != -1) { // read the hash code int hashStartPos = line.IndexOf(" ") + 1; int hashEndPos = line.IndexOf("-->"); origHash = line.Substring(hashStartPos, hashEndPos - hashStartPos); continue; } else { textWithoutHashKey += line + Environment.NewLine; } if (line.IndexOf("<!--NuGetTool") != -1) { int packageStartPos = line.IndexOf("<package"); if (packageStartPos != -1) { int packageEndPos = line.IndexOf("/>", packageStartPos + 1); string uncommentedLine = line.Substring(packageStartPos, packageEndPos - packageStartPos + 2).Trim(); newText += " " + uncommentedLine + Environment.NewLine; } } else { newText += line + Environment.NewLine; } } } // If the file was checked out first time by the tool, and has not changed // outside the tool, then undo the check out when switching back to NuGet mode if (!String.IsNullOrEmpty(origHash)) { File.WriteAllText(packagesConfigFile, textWithoutHashKey); string newHash = GeneralUtils.ComputeHash(packagesConfigFile); File.WriteAllText(packagesConfigFile, newText); // If the files are identical, then undo the checkout if (origHash == newHash) { TFSUtilities.UndoCheckOut(packagesConfigFile, context.TfsServerUri); } } else { File.WriteAllText(packagesConfigFile, newText); } } else { System.Diagnostics.Debug.Write("No packages.config found in " + project.Directory); } }
/// <summary> /// Handle the process of Updating the NuGet packages. /// </summary> /// <param name="preRelease">if set to <c>true</c> [pre release].</param> public static async void UpdateNuGetPackages(bool preRelease) { using (GeneralUtils.StartAnimation()) using (var progress = GeneralUtils.StartProgressProgress("NuGet Upgrade", UPDATE_NUGET_COUNT)) { try { GeneralUtils.ReportStatus($"Start NuGet Upgrade: pre-release = {preRelease}"); OperationContext context = LoadNuGetPackages(preRelease); #region Validation if (context == null) { return; } if (context.Projects.LoadedProjects.Length == 0) { return; } if (context.Projects.IsSolutionInDebugMode()) { GeneralUtils.ShowMessage("Solution is in debug mode. Switch back to NuGet mode before updating the packages.", OLEMSGICON.OLEMSGICON_WARNING); return; } if (!await context.Projects.BuildSolution()) { if (MessageBox.Show(@"Make sure that the solution is build with no errors, before NuGet upgrade! Do you want to continue", "Pre build solution", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { return; } } #endregion // Validation // Build only packages with corresponding projects // in the current solution var packagesToBuild = (from p in context.PackagesInfo where p.ProjectInfo != null select p).ToList(); // Add NuGet packages that have no corrseponding projects in current solution, // but depend on other NuGet packages that need to upgrade var dependentPackagesWithoutProjects = GetDependentPackagesWithoutProjects(context); packagesToBuild.AddRange(dependentPackagesWithoutProjects); #region Validation if (packagesToBuild.Count == 0) { GeneralUtils.ShowMessage(@"No NuGet package needs to be updated. Goto: Tools -> Options -> NuGet Tool and add path for local NuGet repositories."); return; } #endregion // Validation //RemoveCachedNuGetFiles(); context.Projects.CleanSolution(); progress.Report(1); using (var currentProgress = GeneralUtils.StartProgressProgress("NuGet: Current", packagesToBuild.Count)) { DialogResult result = await BuildAndUpdate(context, packagesToBuild, currentProgress); switch (result) { case DialogResult.Cancel: GeneralUtils.ReportStatus("Operation Canceled"); return; case DialogResult.Abort: GeneralUtils.ReportStatus("Operation aborted"); return; } currentProgress.Report(packagesToBuild.Count); } progress.Report(5); if (context.ShouldArchiveOldNuGet) { GeneralUtils.ReportStatus($"NuGet: Archive"); await CreateArchiveZipFile(context.ArchiveSession); } GeneralUtils.ReportStatus($"NuGet: Build"); progress.Report(6); // Build all the other projects that don't have corresponding NuGet packages await BuildProjectsWithNoPackages(context); progress.Report(7); GeneralUtils.ReportStatus($"NuGet: Re-open projects"); await TPL.Task.Factory.StartNew(() => context.Projects.ReOpenSolution(), TPL.TaskCreationOptions.LongRunning); progress.Report(8); #region Clipboard.SetText(context.ArchiveFolder) try { Clipboard.SetText(context.ArchiveFolder); } catch { } #endregion // Clipboard.SetText(context.ArchiveFolder) GeneralUtils.ShowMessage($@"{context.PackagesUpdatedSoFar.Count} NuGet packages have been updated Old packages moved to [{context.ArchiveFolder}] + copied to the clipboard"); } catch (FileNotFoundException ex) { MessageBox.Show($@"Make sure to build the solution before running the tool {ex}", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }