Skip to content

Instantly share code, notes, and snippets.

@EtherZa
Last active July 5, 2021 09:14
Show Gist options
  • Save EtherZa/9bf6eb5577fe9e550e9a6877ae59d7c3 to your computer and use it in GitHub Desktop.
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).
// 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