7

Note I've also asked this question (with reproduction code) on Roslyn's GitHub

  • Create a new solution with 2 projects (CoreLibrary and DownstreamLibrary).
  • Add a project reference from DownstreamLibrary to CoreLibrary.
  • Run the following code and note that DownstreamLibrary no longer compiles.

Note that I've tried net461, netcoreapp2.1 and netstandard2.0 as target frameworks for the projects - same problem each time.

static async Task Main(string[] args)
{
    MSBuildLocator.RegisterDefaults();
    using (var workspace = MSBuildWorkspace.Create())
    {
        workspace.WorkspaceFailed += (sender, workspaceFailedArgs) => WriteLine(workspaceFailedArgs.Diagnostic.Message);
        var solution = await workspace.OpenSolutionAsync(@"c:\source\ForRoslynTest\ForRoslynTest.sln");
        WriteLine($"Loaded solution {solution.FilePath}");

        var projectTree = workspace.CurrentSolution.GetProjectDependencyGraph();
        foreach (var projectId in projectTree.GetTopologicallySortedProjects())
        {
            await CompileProject(workspace.CurrentSolution.GetProject(projectId));
        }
    }
}

private static async Task CompileProject(Project project)
{
    WriteLine($"Compiling {project.Name}. It has {project.MetadataReferences.Count} metadata references.");
    var compilation = await project.GetCompilationAsync();
    var errors = compilation.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error);
    if (errors.Any())
    {
        WriteLine($"COMPILATION ERROR: {compilation.AssemblyName}: {errors.Count()} compilation errors: \n\t{string.Join("\n\t", errors.Where(e => false).Select(e => e.ToString()))}");
    }
    else
    {
        WriteLine($"Project {project.Name} compiled with no errors");
    }
}

You will receive the following output:

Msbuild failed when processing the file 'c:\source\ForRoslynTest\DownstreamLibrary\DownstreamLibrary.csproj' with message: C:\Program Files\dotnet\sdk\2.1.602\Microsoft.Common.CurrentVersion.targets: (1548, 5): The "Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.  Confirm that the <UsingTask> 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.

Found project reference without a matching metadata reference: c:\source\ForRoslynTest\CoreLibrary\CoreLibrary.csproj

Loaded solution c:\source\ForRoslynTest\ForRoslynTest.sln

Compiling CoreLibrary. It has 113 metadata references.
Project CoreLibrary compiled with no errors

Compiling DownstreamLibrary. It has 0 metadata references.
COMPILATION ERROR: DownstreamLibrary: 3 compilation errors:
        c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an assembly reference?)
        c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(5,18): error CS0518: Predefined type 'System.Object' is not defined or imported
        c:\source\ForRoslynTest\DownstreamLibrary\Class1.cs(5,18): error CS1729: 'object' does not contain a constructor that takes 0 arguments

So my question is how do I fix the above errors and get DownstreamLibrary to compile?

EDIT I'm 99% sure the underlying cause is this error

The "Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0

I've confirmed with procmon that it's loading the following DLL (C:\Program Files\dotnet\sdk\2.1.602\Microsoft.Build.Tasks.Core.dll) which I've confirmed with ILSpy DOESN'T have the ResolveNonMSBuildProjectOutput task in it. Older versions of this DLL did have this task.

RB.
  • 36,301
  • 12
  • 91
  • 131
  • I've discovered that if I execute my code as a .net 4.7.2 application, rather than a netcoreapp2.1 application, it works fine. Ideas? – RB. May 30 '19 at 23:07
  • So, there's no obvious resolution to this problem yet and it's indeed a bug tracked in your bug report? – ceztko Dec 29 '19 at 12:13
  • 1
    @ceztko Our application targets `net472` now, as per my comment. As far as I can tell, the MSBuildWorkspace doesn't work with .NET Core (e.g. see [here](https://github.com/dotnet/roslyn/issues/28870)) – RB. Jan 02 '20 at 16:55

1 Answers1

2

I found a manual workaround to this WorkspaceFailed error:

[Failure] Msbuild failed when processing the with message: The "Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput" task could not be loaded from the assembly Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. 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.

There were a few resolution steps:

  1. following https://github.com/microsoft/msbuild/issues/4770 I updated VS 2019 from 16.2 to 16.5.3... This didn't fix my bug, but it's worth documenting I did this.
  2. I upgraded my Microsoft.Build.* and Microsoft.CodeAnalysis dependencies to latest, THIS DIDN'T FIX THINGS YET, same bug.
  3. I navigated to C:\Program Files\dotnet\sdk which previously had a few directories:
1.0.0/                  1.0.0-rc4-004771/  2.0.3/    2.1.505/
1.0.0-preview1-002702/  1.0.3/             2.1.202/  3.1.100/
1.0.0-preview2-003121/  1.0.4/             2.1.4/    3.1.201/
1.0.0-preview4-004233/  1.1.0/             2.1.502/  NuGetFallbackFolder/
  1. I renamed this to sdk_o and created a new folder C:\Program Files\dotnet\sdk, copying in only 3.1.201/

Success! This error was gone, but running my roslyn app then resulted in some error like (paths stripped)

[Failure] Msbuild failed when processing the file with message The "ProcessFrameworkReferences" task failed unexpectedly. System.IO.FileNotFoundException: Could not load file or assembly 'NuGet.Frameworks, Version=5.5.0.4, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified. File name: 'NuGet.Frameworks, Version=5.5.0.4, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

Solved this one by adding NuGet.ProjectModel 5.5.1 to my project, the csproj now has the following package references:

   <ItemGroup>
     <PackageReference Include="Microsoft.Build" Version="16.5.0" ExcludeAssets="runtime" />
     <PackageReference Include="Microsoft.Build.Framework" Version="16.5.0" ExcludeAssets="runtime" />
     <PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
     <PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.5.0" ExcludeAssets="runtime" />
     <PackageReference Include="Microsoft.CodeAnalysis" Version="3.5.0" />
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.5.0" />
     <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="3.5.0" />
     <PackageReference Include="NuGet.ProjectModel" Version="5.5.1" />
   </ItemGroup>

No more WorkspaceFailed events for this code:

Microsoft.Build.Locator.MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();
workspace.WorkspaceFailed += (s, e) => { Console.WriteLine(e.Diagnostic); };
var project = await workspace.OpenProjectAsync(@"C:/path/to.csproj");     

The csproj I'm loading with Roslyn looks as follows:

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <TargetFramework>netcoreapp3.1</TargetFramework>
      <UseWindowsForms>true</UseWindowsForms>
      <OutputType>Library</OutputType>
      <ApplicationIcon />
      <StartupObject />
   </PropertyGroup>

   <ItemGroup>
      <ProjectReference Include="..\..\dependencies\some.csproj" />
   </ItemGroup>
</Project>
Warty
  • 7,237
  • 1
  • 31
  • 49
  • Additionally documented here: https://github.com/dotnet/roslyn/issues/36072#issuecomment-610809322 – Warty Apr 08 '20 at 08:09