dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.24k stars 1.35k forks source link

msbuild nuget package unable to open vs2017 csproj files #2369

Closed weltkante closed 7 years ago

weltkante commented 7 years ago

I'm referencing the nuget packages Microsoft.Build and Microsoft.Build.Tasks.Core. It doesn't matter if I chose stable or prerelease, both versions run into the same error.

I'm trying to open a csproj file for evaluation:

var projectFile = @"C:\projects\test\test.csproj";
var project = new Microsoft.Build.Evaluation.Project(projectFile);
var projectName = Path.GetFileNameWithoutExtension(projectFile);
var outputFile = project.GetPropertyValue("TargetPath");
var outputName = Path.GetFileName(outputFile);

I'm getting Microsoft.Build.Exceptions.InvalidProjectFileException: 'The tools version "15.0" is unrecognized. Available tools versions are "12.0", "14.0", "2.0", "3.5", "4.0".'

When searching the web for this error message I'm only coming up with things related to the VS 2017 installation and how to look up the msbuild packaged with it; unfortunately this doesn't help me with my instance of the exception because I'm invoking msbuild as a library and not as a process.

Do I have to tell the nuget assemblies where the VS 2017 installation is? How do I do this? (I was assuming the nuget assemblies can work stand alone, but if a VS installation is required that works too, it's just not discoverable for me what to do here.)

raffaeler commented 6 years ago

Thank you @rainersigwald ... I made many tests by analyzing my test solution with your code.

so I updated the non-roslyn packages to the latest (the output is similar to this, but I didn't capture the one of my update): image (they are just roslyn dependencies, the only one I directly use is the tuple package) Then I updated the Roslyn from 1.32 to 2.6.1 and now works.

Now the only difference between mine and your solutions is that I also reference Microsoft.Build.* packages while you don't (should I remove them?)

Where is the wizardry? Is the compilation process dependent from a specific version of system.composition package?

P.S. yes, I have binding redirects in my solution which were automatically updated by the nuget process.

matkoch commented 6 years ago

@rainersigwald my use case is just to evaluate MSBuild properties, like Configuration, TargetFrameworks, PackageReferences, included files, and so on. My goal is that this works cross platform with .NET Framework, Mono, and of course also .NET Core tooling (without any VS installed at all). Roslyn/C# is completely out of scope.

Just a moment ago, I created a simple repro with netcoreapp2.0, references to Microsoft.Build and Microsoft.Build.Utilities.Core and this code:

var projectCollection = new ProjectCollection();
var project = new Project(@"..\ConsoleApp10.csproj",
        new Dictionary<string, string>(),
        projectCollection.DefaultToolsVersion);

var lookup = project.Items.ToLookup(x => x.ItemType, x => x.EvaluatedInclude);

I tried this w/ and w/o binding redirects. Always fails with:

The SDK 'Microsoft.NET.Sdk' specified could not be found.

matkoch commented 6 years ago

Ping @rainersigwald. Could you please also re-open this issue? It is obviously not solved.

ulrichb commented 6 years ago

@rainersigwald This is a blocking issue for me too. /cc @matkoch

matkoch commented 6 years ago

@rainersigwald kindly pinging....

flagbug commented 6 years ago

I'm having the same problem that @matkoch is having. I'm working on a cross-platform tool that analyzes outdated packages (https://github.com/goenning/dotnet-outdated) and really just want to read the package references of a simple project file.

The problem is that this always throws The SDK 'Microsoft.NET.Sdk.Web' specified could not be found. for some reason

p-kaczynski commented 6 years ago

Having same problem, but only when using .netcore2.0, works fine in .net framework.

p-kaczynski commented 6 years ago

Literally changing from <TargetFramework>netcoreapp2.0</TargetFramework> to <TargetFramework>net461</TargetFramework> fixes the issue for me using

<PackageReference Include="Microsoft.Build" Version="15.6.85" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.6.85" />

and new Project(path)

CodeTroopers commented 6 years ago

I had the same issue with a TFS Build Agent (Version 2010) after installing Build Tools for Visual Studio 2017 and configuring MSBuild arguments to : /toolsversion:15.0 /property:VisualStudioVersion=15.0. It seems this registery key is missing : HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\15.0 with the string value MSBuildToolsPath and cause the error :

'The tools version "15.0" is unrecognized. Available tools versions are "12.0", "14.0", "2.0", "3.5", "4.0".'

manish10sharma commented 6 years ago

Hello I am having the same issue. MSB4062 The "Microsoft.CodeAnalysis.BuildTasks.Csc" task could not be loaded from the assembly C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Roslyn\Microsoft.Build.Tasks.CodeAnalysis.dll. Could not load file or assembly 'Microsoft.Build.Utilities.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. MSBuild C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Roslyn\Microsoft.CSharp.Core.targets 52 false Error

Can Anyone tell me solution if found? I am using 2017 15.8.2 Version.

Please help. Thanks

kjkrum commented 6 years ago

I'm got the same error when opening the csproj of one project from another project. Both projects were freshly created today in VS2017 15.8.8. Updating to 15.8.9 did not help.

using (var col = new ProjectCollection())
{
    var proj = col.LoadProject(projectFile); // kaboom!
}

Installing the latest Microsoft.Build and Microsoft.Build.Utilities.Core from nuget solved the problem. I didn't even need to fiddle around with environment variables. Why does VS still ship with a broken MSBuild?

weltkante commented 6 years ago

@kjkrum

Why does VS still ship with a broken MSBuild?

As far as I know VS no longer ships MSBuild (it ships via nuget). VS has its own private copy of MSBuild which is not exposed to your project build so you can't reference it.

If you reference MSBuild through the GAC or Assembly Reference list (i.e. not through nuget) you likely get some outdated version which previously shipped with the .NET framework or an older VS and thus still is visible there for backwards compatibility.

rainersigwald commented 6 years ago

You can and should use the VS copy of MSBuild, but since it's no longer in the GAC you must locate it. https://docs.microsoft.com/en-us/visualstudio/msbuild/updating-an-existing-application has details on what's required, and https://github.com/Microsoft/MSBuildLocator/ is a package used to make the process easier.

kjkrum commented 6 years ago

@rainersigwald That's an awful lot of dicking around for something that used to be a checkbox.

aolszowka commented 5 years ago

This is still present. The work around provided by @rainersigwald and documented here https://docs.microsoft.com/en-us/visualstudio/msbuild/updating-an-existing-application?view=vs-2017 (specifically using MSBuildLocator.RegisterDefaults();) worked for us.

kurtnelle commented 5 years ago

Any solution for this. I'm having a similar issue with trying to create a Raspberry Pi Blink project. The project creation fails with the error message "Unable to read the project file "Blink12.vcxproj" The tools version "15.0" is unrecognized. Available tools versions are "2.0","3.5","4.0"

rainersigwald commented 5 years ago

@kurtnelle If https://docs.microsoft.com/en-us/visualstudio/msbuild/updating-an-existing-application doesn't help you, please open a new issue with more details about how you're using the API and what's going wrong.

GeirGrusom commented 4 years ago

Seriously this is a huge issue for me. Old version of the libraries don't work with 2019 only systems and new versions doesn't work with 2017 only systems. I even made a shim that would use new versions on systems with 2019 installed but old in 2017 systems. It seemed like it worked but the integration tests that looked like they worked everywhere else fails on the build server. I don't want that stupid hack to begin with and now it unsurprisingly fails in the most important configuration.

I've been struggling with this for almost a month. The error message is non-sensical and unhelpful, and this is obviously a major breaking change in the library. Why does upgrading to new versions, with no other changes at all, break simply loading the project in 2017? Just calling "LoadFromXmlReader" throws this error. Setting toolsversion and subtoolsetversion seems to have absolutely no effect what.so.ever.

This thing makes me extremely unproductive and it makes me look incompetent.

rainersigwald commented 4 years ago

@GeirGrusom can you please file a new issue, including details on

Old version of the libraries don't work with 2019 only systems and new versions doesn't work with 2017 only systems.

What libraries?

Why does upgrading to new versions, with no other changes at all, break simply loading the project in 2017?

Can you provide more details on exactly how you're loading projects and what the system environment is (upgrading from what to what)?

GeirGrusom commented 4 years ago

I'm very sorry. I was very stressed on friday, but that's no excuse for unprofessional behavior.

Short about the appliation: It's used for building solutions, versioning and running the test suite on them. I would argue the value of this in the first place but that's unfortunately not particularily productive. It first invokes vswhere to find out where Visual Studio is located and uses that to actually build the application. This failed earlier because it wouldn't try to use Visual Studio 2019 if a project was made with 2017 and specified that so I updated the vswhere implementation to find the latest if an exact match could not be found. This seems to work: projects build just fine.

However the issues show up when running the test suites. It uses Microsoft.Build to load the project files in order to find the output DLL files and dependencies the projects might have. On the old version this worked fine for 2017 but in 2019 it gave this odd error:

error MSB1040: ToolsVersion is not valid. The tools version "15.0" is unrecognized. Available tools versions are "2.0", "3.5", "4.0".

Build libraries are Microsoft.Build and Microsoft.Build.Utilities.Core at version 15.9.20.

I tried to just change "tools" version but this error shows up with different versions except if I put 4.0, at which point it tells me that it can't find Microsoft.NET.Sdk. I upgrade to 16.4.0 on both libraries and now it works in 2019, but on systems with 2017 installed I'm back to the drawing board. So I made this shim that will force it on a newer version as explained and now in all environments I've tested it it works but it is hacky and not exactly very maintenable. It also fails to build on the build server with the same error when it tries to run integration tests with this issues error description.

It seems to me that there's some confusion as to what "toolsVersion" actually mean. Take Microsoft.Build.Utilities.ToolLocationHelper.GetPathToBuildTools(string). In the documentation it looks to me like it should return the location of MSBuild, but it doesn't do that at all. Sometimes it seems to return the entry assembly path, and other times .NET Framework paths, and on my development machine it returns exactly what I would expect.

What does toolsVersion mean? Is it CLR version? MSBuild version? Visual Studio version? The documentaiton on MSBuild...Project.LoadFromStream is not exactly helpful as it just says "that's the tools version" more or less. If I state nothing it seems like MSBuild will put toolsversion from the <Project /> element or whatever SDK it ends up loading and that's what's causing this odd error message. Change the toolsversion and it will complain about wrong toolsversions until you hit 4.0, 3.5 or 2.0 at which point it will complain that Microsoft.NET.Sdk could not be found. Is MSBuild doing the wrong thing here, or is the error description wrong?

I'll see if I can make a trivial reproduction.

GeirGrusom commented 4 years ago

Couldn't reproduce the issue in a trivial solution. Only new project does not properly load in VS2019 but I got everything to work on build so I don't think I want to waste anymore of your time on this.

Thanks, and again, sorry.

rainersigwald commented 4 years ago

@GeirGrusom I think you might like to use MSBuildLocator in your application. It handles the scenarios you're currently using VSWhere for, and you should be able to use a single application to load both 2017 and 2019 projects (as long as you reference MSBuild 15.x when you build).