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.