Old csproj to new csproj: Visual Studio 2017 upgrade guide

I love the new VS2017! I really love it.

My new project files look clean, and are easier to understand.

That is why I loved so much Nate McMaster post about how to change your projects to the new VS2017.

I have been thinking on creating a tool to migrate my old projects but I only had 20 minutes. So I decided at least to create a script for lazy people like me to speed up the tedious project of creating your new projects from scratch.

This .csx script will just create take the old project file as input, create a new one based on a template and copy all nugets packages as package references.

It has a been a time saver. Note: You cannot fully upgrade your windows forms projects with this because the designer does not work with this new project format.

Ok. this is the gist: https://gist.github.com/orellabac/392989fbc0c4061acfa1ca33dc3a51c2

And you can see the code below.

using System;
using System.IO;
using System.Xml;

const string classLibraryTemplate =
@"
<Project Sdk=""Microsoft.NET.Sdk"">
  <PropertyGroup>
    <TargetFramework>net461</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
##Packages
  </ItemGroup>
</Project>
";

const string exeTemplate = @"
<Project Sdk=""Microsoft.NET.Sdk"">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net461</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
##Packages
  </ItemGroup>
</Project>
";

const string testTemplate =
@"
<Project Sdk=""Microsoft.NET.Sdk"">
  <PropertyGroup>
    <TargetFramework>net46</TargetFramework>
  </PropertyGroup>
  <ItemGroup>##Packages</ItemGroup>
  <ItemGroup>
    <PackageReference Include=""Microsoft.NET.Test.Sdk"" Version=""15.0.0"" />
    <PackageReference Include=""xunit"" Version=""2.2.0"" />
    <PackageReference Include=""xunit.runner.visualstudio"" Version=""2.2.0"" />
  </ItemGroup>
  <ItemGroup>
##Packages
  </ItemGroup>

</Project>
";


string ConvertPackages(string fullPathToProject)
{
    var packagesStr = new System.Text.StringBuilder();
    var projectDir = Path.GetDirectoryName(fullPathToProject);
    var packagesFile = Path.Combine(projectDir, "packages.config");
    if (File.Exists(packagesFile))
    {
        var doc = new XmlDocument();
        doc.Load(packagesFile);
        var packages = doc.SelectNodes("//package");
        foreach (System.Xml.XmlElement p in packages)
        {
            packagesStr.AppendLine($"<PackageReference Include=\"{p.Attributes["id"].Value}\" Version=\"{p.Attributes["version"]}\" />");
        }
    }
    return packagesStr.ToString();
}

void ConvertLibrary(string fullPathToProject) {
    var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fullPathToProject);
    var newProjectFile = Path.Combine(fileNameWithoutExt, ".New.csproj");
    var packages = ConvertPackages(fullPathToProject);
    File.WriteAllText(newProjectFile, classLibraryTemplate.Replace("##Packages", packages));
}

void ConvertExe(string fullPathToProject) {
    var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fullPathToProject);
    var newProjectFile = Path.Combine(fileNameWithoutExt, ".New.csproj");
    var packages = ConvertPackages(fullPathToProject);
    File.WriteAllText(newProjectFile, exeTemplate.Replace("##Packages", packages));

}

void ConvertTest(string fullPathToProject) {
    var fileNameWithoutExt = Path.GetFileNameWithoutExtension(fullPathToProject);
    var newProjectFile = Path.Combine(fileNameWithoutExt, ".New.csproj");
    var packages = ConvertPackages(fullPathToProject);
    File.WriteAllText(newProjectFile, testTemplate.Replace("##Packages", packages));

}

I think I will write a more complete tool to migrate projects later.