Last active
July 5, 2021 09:14
-
-
Save EtherZa/9bf6eb5577fe9e550e9a6877ae59d7c3 to your computer and use it in GitHub Desktop.
Visual Commander script to retarget all loaded Visual Studio projects to a specified .net version (TargetFramework).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Retarget all loaded projects to the .net version specified in "TargetFramework" | |
// Execute with Visual Commander (https://marketplace.visualstudio.com/items?itemName=SergeyVlasov.VisualCommander) | |
// ********************************************************** | |
// NOTE: NuGet packages need to be reinstalled post execution | |
// ********************************************************** | |
using EnvDTE; | |
using EnvDTE80; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Threading; | |
public class C : VisualCommanderExt.ICommand | |
{ | |
const string FrameworkMoniker = "TargetFrameworkMoniker"; | |
const string TargetFramework = ".NETFramework,Version=v4.6.2"; | |
public void Run(EnvDTE80.DTE2 dte, Microsoft.VisualStudio.Shell.Package package) | |
{ | |
var bw = new BackgroundWorker(); | |
bw.DoWork += DoWork; | |
bw.ProgressChanged += ProgressChanged; | |
bw.RunWorkerCompleted += RunWorkerCompleted; | |
bw.WorkerReportsProgress = true; | |
bw.RunWorkerAsync(dte); | |
} | |
private void ReportProgress(EnvDTE80.DTE2 dte, BackgroundWorker bw, string messageFormat, params object[] p) | |
{ | |
var state = new State(dte, string.Format(messageFormat, p)); | |
bw.ReportProgress(0, state); | |
System.Threading.Thread.Sleep(100); | |
} | |
private void DoWork(object sender, DoWorkEventArgs e) | |
{ | |
var bw = (BackgroundWorker)sender; | |
var dte = (EnvDTE80.DTE2)e.Argument; | |
var projects = (from p in GetProjects(dte.Solution) | |
where p.Properties != null | |
let m = p.Properties.Item(FrameworkMoniker) | |
where m != null && !m.Value.Equals(TargetFramework) | |
orderby p.Name | |
select new | |
{ | |
Project = p, | |
TargetFramework = m | |
}).ToList(); | |
ReportProgress(dte, bw, "Converting {0} projects to {1}:\r\n", projects.Count, TargetFramework); | |
for (var i = 0; i < projects.Count; i++) | |
{ | |
var item = projects[i]; | |
var project = item.Project; | |
ReportProgress(dte, bw, "[{0}/{1}] {2} ({3})", i+1, projects.Count, project.Name, item.TargetFramework.Value); | |
item.TargetFramework.Value = TargetFramework; | |
ReportProgress(dte, bw, " ...done.\r\n"); | |
} | |
} | |
private void ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) | |
{ | |
var state = (State)e.UserState; | |
Log(state.Dte, state.Message); | |
} | |
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) | |
{ | |
var dte = (EnvDTE80.DTE2)e.UserState; | |
if (e.Cancelled) | |
{ | |
Log(dte, "Operation was canceled"); | |
return; | |
} | |
if (e.Error != null) | |
{ | |
Log(dte, "An error occurred: {0}", e.Error.Message); | |
return; | |
} | |
Log(dte, "Completed"); | |
} | |
public static void Log(EnvDTE80.DTE2 dte, string messageFormat, params object[] p) | |
{ | |
Window window = dte.Windows.Item(EnvDTE.Constants.vsWindowKindOutput); | |
OutputWindow outputWindow = (OutputWindow) window.Object; | |
outputWindow.ActivePane.Activate(); | |
outputWindow.ActivePane.OutputString(string.Format(messageFormat, p)); | |
} | |
public static IList<Project> GetProjects(EnvDTE.Solution solution) | |
{ | |
var list = new List<Project>(); | |
foreach (var item in solution.Projects) | |
{ | |
var project = item as Project; | |
if (project == null) | |
{ | |
continue; | |
} | |
if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder) | |
{ | |
list.AddRange(GetSolutionFolderProjects(project)); | |
} | |
else | |
{ | |
list.Add(project); | |
} | |
} | |
return list; | |
} | |
private static IEnumerable<Project> GetSolutionFolderProjects(Project solutionFolder) | |
{ | |
List<Project> list = new List<Project>(); | |
for (var i = 1; i <= solutionFolder.ProjectItems.Count; i++) | |
{ | |
var subProject = solutionFolder.ProjectItems.Item(i).SubProject; | |
if (subProject == null) | |
{ | |
continue; | |
} | |
// If this is another solution folder, do a recursive call, otherwise add | |
if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) | |
{ | |
list.AddRange(GetSolutionFolderProjects(subProject)); | |
} | |
else | |
{ | |
list.Add(subProject); | |
} | |
} | |
return list; | |
} | |
public class State | |
{ | |
public State(EnvDTE80.DTE2 dte, string message) | |
{ | |
Dte = dte; | |
Message = message; | |
} | |
public EnvDTE80.DTE2 Dte { get; set; } | |
public string Message { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment