How to run Visual Studio 2017 projects using Build Tools for Visual Studio

One of the biggest changes Microsoft did lately in the .Net eco-system is a new version of MSBuild.
This version advocates smaller, light weight MSBuild files, that consolidate the entire .Net project functionality, like NuGet support (previously with packages.config files), .Net Core and .Net Standard builds (previously project.json) and AssemblyInfo props. There are also treats like live csproj editing, no file listing, multi-framework targeting and more.
Now the csproj includes all the definitions of a .Net project.

When running builds on CI build machines, its a common practice not to install VS but only to install the build tools required, creating a cleaner eco-system for builds.
Microsoft releases an installation of the new build tools with each release of VS.

Although it seems like installing the build tools is enough, in 2017 version there are a couple of issues with the current installation, preventing projects to build properly, using only the Build tools distribution.
These issues are caused due to MSBuild target files missing from the installation.

Installing Build Tools

You can find the build tools for VS2017 (the new version of MSBuild) here under Other tools and frameworks.

You can run the installation by running this command line:
vs_buildtools.exe --add Microsoft.VisualStudio.Workload.MSBuildTools --quiet

The build tools will be installed at c:\Program Files(x86)\Visual Studio\2017\Build Tools\MSBuild

Micosoft.NET.Sdk targets

The new format of MSBuild is based on a new type of project: Microsoft.NET.Sdk. Projects are defined with this type declaring the affiliation to the new build system:

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

When MSBuild runs the project, its will need import props and targets relating to this type of project, allowing multi targeting for example.
These are supposed to be found under in the following folder c:\Program Files(x86)\Visual Studio\2017\Build Tools\MSBuild\Sdks.

When trying to run msbuild on a csproj file with the above, the build fails with the following error:

error MSB4019: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props" was not found.  
Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.  

Browsing in the machine's file system reveals that the Sdks folder is missing.

Solution

Copy the Sdks folder from a machine that has VS2017 installed at:
c:\Program Files(x86)\Visual Studio\2017\Professional\Build MSBuild\Sdks
to your build machine at:
c:\Program Files(x86)\Visual Studio\2017\Build Tools\MSBuild\Sdks

Now its possible to run build, rebuild and clean targets on your project.

NuGet targets

In VS2017, NuGet became a first class citizen in the Visual Studio build system.
NuGet package dependency is defined in the csproj file:

<ItemGroup>  
    <PackageReference Include="MySql.Data" Version="6.9.9" />
    ...
</ItemGroup>  

Visual Studio will automatically restore the package, without the need to create a file reference.

In technical terms, VS imports targets related to NuGet into the msbuild run, like restore:
msbuild /t:restore MyProject.csproj
You can read more about it in Microsoft's docs.

Running this command on a machine with VS installed will result a successful build.
For machines with only Build Tools, the build will fail with the following error:

error MSB4057: The target "restore" does not exist in the project  

The issue is the same as before - missing files which include the targets and props for running NuGet commands in msbuild context.

Running msbuild in verbose mode (msbuild /verbosity:diag ...) reveals that msbuild actually trying to find these, but comes up empty:

...
Trying to import C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\$(MSBuildToolsVersion)\Microsoft.Common.targets\ImportAfter\*.NuGet.*.targets using extensions path C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild  
...

Yeah, this is indeed a WTF moment...

Solution

Copying the NuGet import files will do the tr
Again, from a machine with VS2017, copy the following folder:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\NuGet
to your build machine at:
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\IDE\CommonExtensions\Microsoft\NuGet

Now NuGet related targets, like restore and pack, will be available.

Final notes

There are several open issues in Microsoft's github account (like this one) relating to these issues, so I guess it will be solved soon.

In the meantime, you can start running VS2017 projects on your CI and build machines using these solutions.

Yossi Shmueli

Keeping it green since 1995

comments powered by Disqus