Since Visual Studio 2017 is out, and we have a 1.0.0 tools release for .Net Core, I’m going to try and migrate a simple project from the pre-release tooling, onto the new tooling.

The biggest difference is that instead of using a project.json file, the new tooling now uses a .csproj file instead. It will take a few more posts to go into the differences and re-learn how this works, so for now lets just get something building.

A v-previous dotnet new

I have a standard project created with dotnet new in my folder. This is an app (the default when you use new without parameters) and has two files: project.json and program.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyNewApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            if(!Console.IsInputRedirected){
            Console.ReadKey();
            }
        }
    }
}
{
  "version": "1.0.0-*",
  "buildOptions": {
    "emitEntryPoint": true,
    "debugType": "portable"
  },
  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0"
    }
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }
}

Now that I have VS 2016 installed, I can’t build this project. I get an error:

MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

Migration

Luckily, there is a dotnet migrate command. If you run dotnet help migrate you get some useful usage information:

.NET Migrate Command

Usage: dotnet migrate [arguments] [options]

Arguments:
  <PROJECT_JSON/GLOBAL_JSON/SOLUTION_FILE/PROJECT_DIR>  The path to one of the following:
    - a project.json file to migrate.
    - a global.json file, it will migrate the folders specified in global.json.
    - a solution.sln file, it will migrate the projects referenced in the solution.
    - a directory to migrate, it will recursively search for project.json files to migrate.
Defaults to current directory if nothing is specified.

Options:
  -h|--help                     Show help information
  -t|--template-file            Base MSBuild template to use for migrated app. The default is the project included in dotnet new.
  -v|--sdk-package-version      The version of the sdk package that will be referenced in the migrated app. The default is the version of the sdk in dotnet new.
  -x|--xproj-file               The path to the xproj file to use. Required when there is more than one xproj in a project directory.
  -s|--skip-project-references  Skip migrating project references. By default project references are migrated recursively.
  -r|--report-file              Output migration report to the given file in addition to the console.
  --format-report-file-json     Output migration report file as json rather than user messages.
  --skip-backup                 Skip moving project.json, global.json, and *.xproj to a `backup` directory after successful migration.

So as you can see, you can migrate a solution, a project, or use a global.json to migrate multiple projects. You can even use -t to migrate as a specific type of project. Since this defaults to the same template used for dotnet new, and that I am running this from the project folder, I can just use dotnet migrate.

This produces the following results:

Project dotnetprevious migration succeeded (C:\dev\temp\dotnetprevious).
Summary
Total Projects: 1
Succeeded Projects: 1
Failed Projects: 0

The project migration has finished. Please visit https://aka.ms/coremigration to report any issues you've encountered or ask for help.
Files backed up to C:\dev\temp\dotnetprevious\backup\

Let’s see where we are:

dotnetprevious
 |-- dotnetprevious.csproj
 |-- Program.cs
 |-- backup
 |    +-- project.json
 |
 +-- obj
      |-- ...

So we can see that our project.json has been moved out of the way and replaces with a .csproj file. We still have our project.json file to refer to as well, in case anything is missing.

Build it

Now we have migrated, we can restore, build and run:

dotnet restore
dotnet build
dotnet run

Success!

Hello World!

The csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.0</TargetFramework>
    <DebugType>portable</DebugType>
    <AssemblyName>dotnetprevious</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>dotnetprevious</PackageId>
    <RuntimeFrameworkVersion>1.0.4</RuntimeFrameworkVersion>
    <PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
  </PropertyGroup>

</Project>

A pretty simple xml file, with a property group for some of the (familiar) properties we might want set on our project. We see that TargetFramework is netcoreapp1.0, which is what makes this a new .csproj vs the older .csproj files.

Conclusion

Simple migration seems to work, and is simple to apply. I am hoping as more complex project migration comes around it is just as easy. Don’t forget that -t argument to use the right app, web, lib or test template as you migrate if required.

Also be aware that after migration, everyone will have to move to Visual Studio 2017, and the new dotnet 1.0.0 sdk before they can now build and run this now migrated project.

Update (13/3)

I have since learned that you can safely have all versions installed and running on the same machine. To make this work, just specify the correct sdk version in your global.json file, and the correct version of the sdk will be used.

{
  "projects": [
    "."
  ],
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}

There is also a separate setting used for launchsettings.json, but I won’t give specifics on that since I am unfamiliar with it.