Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET Core App fails to load project (.NET 4.6.1 works as expected) #3434

Open
paulvanbrenk opened this issue Jun 20, 2018 · 19 comments
Open
Assignees

Comments

@paulvanbrenk
Copy link

I created a sample .NET Console app with the following code.

using System;
using Microsoft.Build.Evaluation;

namespace ConsoleApp25
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var buildEngine = new ProjectCollection();
            var project = buildEngine.LoadProject("<full path>\\UnitTestProject.csproj");
       }
    }
}

My project references the following 2 Nuget packages:

  • Microsoft.Build
  • Microsoft.Build.Utilities.Core

This gives the following exception when compiled to target .NET Core 2.0;

Microsoft.Build.Exceptions.InvalidProjectFileException
  HResult=0x80131500
  Message=The SDK 'Microsoft.NET.Sdk' specified could not be found.  d:\dd\GitHubTestAdapter\UnitTestProject\UnitTestProject.csproj
  Source=Microsoft.Build
  StackTrace:
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args) in /_/src/Shared/ProjectErrorUtilities.cs:line 412
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(String directoryOfImportingFile, ProjectImportElement importElement, List`1& projects, Boolean throwOnFileNotExistsError) in /_/src/Build/Evaluation/Evaluator.cs:line 2173
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImports(String directoryOfImportingFile, ProjectImportElement importElement) in /_/src/Build/Evaluation/Evaluator.cs:line 1944
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in /_/src/Build/Evaluation/Evaluator.cs:line 1823
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in /_/src/Build/Evaluation/Evaluator.cs:line 940
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(ILoggingService loggingService, BuildEventContext buildEventContext) in /_/src/Build/Evaluation/Evaluator.cs:line 726
   at Microsoft.Build.Evaluation.Project.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in /_/src/Build/Definition/Project.cs:line 2752
   at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in /_/src/Build/Definition/Project.cs:line 2719
   at Microsoft.Build.Evaluation.Project.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext) in /_/src/Build/Definition/Project.cs:line 2822
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext) in /_/src/Build/Definition/Project.cs:line 543
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, IDictionary`2 globalProperties, String toolsVersion) in /_/src/Build/Definition/ProjectCollection.cs:line 1118
   at ConsoleApp25.Program.Main(String[] args) in D:\tmp\source\repos\ConsoleApp25\ConsoleApp25\Program.cs:line 11

However it works as expected when targeting .NET 4.6.1

Any ideas?

ConsoleApp25.zip

@rainersigwald
Copy link
Member

Can you see if the documentation at https://docs.microsoft.com/en-us/visualstudio/msbuild/updating-an-existing-application helps? Feedback welcome, but I think it addresses your use case.

@paulvanbrenk
Copy link
Author

The documentation suggests it would, but I can't access the MSBuildLocator type in my .NET Core app. (The assemblies in the package only target .NET 4.6).

@paulvanbrenk
Copy link
Author

When I run the project from the command line (using dotnet run), I get some more information:

Unhandled Exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "C:\vs\dogfood\MSBuild\15.0\Bin\15.0\Microsoft.Common.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.  C:\Program Files\dotnet\sdk\2.1.400-preview-008963\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args) in /_/src/Shared/ProjectErrorUtilities.cs:line 412
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpression(String directoryOfImportingFile, ProjectImportElement importElement, String unescapedExpression, Boolean throwOnFileNotExistsError, List`1& imports) in /_/src/Build/Evaluation/Evaluator.cs:line 2418
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(String directoryOfImportingFile, ProjectImportElement importElement, List`1& projects, Boolean throwOnFileNotExistsError) in /_/src/Build/Evaluation/Evaluator.cs:line 2173
   at Microsoft.Build.Evaluation.Evaluator`4.ExpandAndLoadImports(String directoryOfImportingFile, ProjectImportElement importElement) in /_/src/Build/Evaluation/Evaluator.cs:line 1944
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in /_/src/Build/Evaluation/Evaluator.cs:line 1823
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in /_/src/Build/Evaluation/Evaluator.cs:line 997
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement) in /_/src/Build/Evaluation/Evaluator.cs:line 1825
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport) in /_/src/Build/Evaluation/Evaluator.cs:line 940
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(ILoggingService loggingService, BuildEventContext buildEventContext) in /_/src/Build/Evaluation/Evaluator.cs:line 726
   at Microsoft.Build.Evaluation.Project.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in /_/src/Build/Definition/Project.cs:line 2752
   at Microsoft.Build.Evaluation.Project.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings) in /_/src/Build/Definition/Project.cs:line 2719
   at Microsoft.Build.Evaluation.Project.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext) in /_/src/Build/Definition/Project.cs:line 2822
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext) in /_/src/Build/Definition/Project.cs:line 543
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, IDictionary`2 globalProperties, String toolsVersion) in /_/src/Build/Definition/ProjectCollection.cs:line 1118
   at ConsoleApp25.Program.DoWork() in d:\tmp\source\repos\ConsoleApp25\ConsoleApp25\Program.cs:line 44
   at ConsoleApp25.Program.Main(String[] args) in d:\tmp\source\repos\ConsoleApp25\ConsoleApp25\Program.cs:line 37

The only Microsoft.Common.props file I can find in my VS install directory is:
C:\vs\dogfood\MSBuild\15.0\Microsoft.Common.props.

@KirillOsenkov
Copy link
Member

I can confirm that it doesn't work when Paul's app that uses MSBuild is targeting netcoreapp20:

Unhandled Exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\15.0\Microsoft.Common.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.  C:\Program Files\dotnet\sdk\2.1.300-preview1-008174\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props

Looks like in both cases it's appending an unnecessary \15.0 to the path to Microsoft.Common.props.

Adding some SDK experts @dsplaisted @nguerrera. Still not sure if the bug is in the SDK or elsewhere, but hopefully someone can shed some light. The repro is easy (just had to change the hardcoded path to the test project on Paul's drive).

@baruchiro
Copy link

It is becoming more and more required, depending on the porting to the .net core.
At the moment I don't see any libraries that provide the capabilities that this library provides, and there is no library that supports net core.
Can anyone direct me to where the solution might be? I'm not yet familiar with the MSBuild code.

@Alxandr
Copy link

Alxandr commented Jun 19, 2019

I just hit this issue. Are there any known workarounds?

@rainersigwald
Copy link
Member

MSBuildLocator now supports .NET Core applications. Are you using it, @Alxandr?

@Alxandr
Copy link

Alxandr commented Jun 19, 2019

I'm using nuke-build. So I'm not directly using anything. I might look into it though.

@Alxandr
Copy link

Alxandr commented Jun 19, 2019

I tried doing the following:

using System;
using System.Collections.Generic;
using System.Text;

static class Program
{
    public static int Main()
    {
        Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();
        return Build.Run();
    }
}

And I still got the same error.

Here's output from the immediate window before doing Build.Run() (I inserted > in front of the input lines):

> Microsoft.Build.Locator.MSBuildLocator.IsRegistered
true
> Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH")
"C:\\Program Files\\dotnet\\sdk\\2.2.300\\MSBuild.dll"

Edit:
And it's failing here: https://github.com/nuke-build/common/blob/35404e91f1a283cddf5e5659ef7011ba44d17873/source/Nuke.Common/ProjectModel/ProjectModelTasks.cs#L47

@LegendaryB
Copy link

Any news on this issue?

@dsplaisted
Copy link
Member

@Forgind @benvillalobos

As far as I know MSBuildLocator should work on .NET Core. I'm not sure what the issue with nuke-build was, or whether it's been resolved yet.

@Forgind
Copy link
Member

Forgind commented Feb 5, 2021

It should, yes. @Alxandr, would you mind sharing the version of your repro that used MSBuildLocator?

@Alxandr
Copy link

Alxandr commented Feb 5, 2021

I don't even remember which project I was using this on anymore, so I'm not going to to try to recreate it half a year later, sorry.

@KirillOsenkov
Copy link
Member

KirillOsenkov commented Feb 5, 2021

I can still easily reproduce the problem:

Use this .csproj:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

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

</Project>

and this .cs:

using Microsoft.Build.Evaluation;

class Program
{
    private static void Main(string[] args)
    {
        var buildEngine = new ProjectCollection();
        var project = buildEngine.LoadProject("some.csproj");
    }
}

It works fine if you're targeting net472, but fails if you're targeting net5.0.

To workaround, you need to add a reference to Microsoft.Build.Locator. Change the .csproj to this:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Build" Version="16.8.0" ExcludeAssets="runtime" />
    <PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.8.0" ExcludeAssets="runtime"/>
  </ItemGroup>

</Project>

and the .cs to this:

using Microsoft.Build.Evaluation;

class Program
{
    private static void Main(string[] args)
    {
        Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();
        Test();
    }

    private static void Test()
    {
        var buildEngine = new ProjectCollection();
        var project = buildEngine.LoadProject("C:\\temp\\multi\\a\\a.csproj");
    }
}

Note how the first usage of MSBuild API has to be in a separate method, because otherwise JIT will try to resolve Microsoft.Build.dll before MSBuildLocator was registered.

I'm still curious why the desktop version works without MSBuildLocator, but .NET 5 version needs it.

@Forgind
Copy link
Member

Forgind commented Feb 5, 2021

I'm still curious why the desktop version works without MSBuildLocator, but .NET 5 version needs it.

The part of this that confuses me is not that it doesn't work with .NET 5 but that it works with .NET Framework. It's meaningless to say you need __ part of the MSBuild API if you don't specify which version of MSBuild you want to use. That suggests to me that there's some default logic that tries to guess which MSBuild you are trying to use, in which case it would make sense that it would only be right if it knows what framework to use, and it presumably hasn't been updated since Core came out. I'm curious what would happen if you tried it on a computer with Core MSBuild but not Framework MSBuild.

@rizi
Copy link

rizi commented Mar 10, 2022

For me everything works with .net 5.0, but as soon as I use .net 6.0 I have to use
Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();

any updates on this issue (at least for .net 6.0)?

@Forgind
Copy link
Member

Forgind commented Mar 10, 2022

What versions of MSBuild do you have? If you have net5.0 and net6.0 but nothing lower, that might validate my guess.

@rizi
Copy link

rizi commented Mar 10, 2022

What versions of MSBuild do you have? If you have net5.0 and net6.0 but nothing lower, that might validate my guess.

I will check tomorrow, but I have VS 2019 and VS 2022 installed. .net core 3, .net 5 and .net 6.0 SDKs and runtimes.

I also have.net 4.7.2 installed.
So I think I have the latest version of msbuild and at least one version before the latest version.
Br

@Forgind
Copy link
Member

Forgind commented Mar 10, 2022

Ah, ok. Not what I'd been hoping, then. Thanks for checking.

@AR-May AR-May added the triaged label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants