MSBuildWorkspace не может скомпилировать проект с <ProjectReference>в другой проект - PullRequest
0 голосов
/ 31 мая 2019

Примечание. Я также задавал этот вопрос (с кодом воспроизведения) на GitHub Рослина

  • Создание нового решения с 2 проектами (CoreLibrary и DownstreamLibrary).
  • Добавление ссылки на проект из DownstreamLibrary в CoreLibrary.
  • Запустите следующий код и обратите внимание, что DownstreamLibrary больше не компилируется.

Обратите внимание, что я использовал net461, netcoreapp2.1 и netstandard2.0 в качестве целевых структур для проектов - одна и та же проблема каждый раз.

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");
    }
}

Вы получите следующий вывод:

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

Итак, мой вопрос: как исправить вышеуказанные ошибки и заставить DownstreamLibrary скомпилироваться?

EDIT Я на 99% уверен, что основной причиной является эта ошибка

Не удалось загрузить задачу «Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput» из сборки Microsoft.Build.Tasks.Core, версия = 15.1.0.0

Я подтвердил с помощью procmon, что он загружает следующую DLL (C: \ Program Files \ dotnet \ sdk \ 2.1.602 \ Microsoft.Build.Tasks.Core.dll), которую я подтвердил с помощью ILSpy НЕ содержит задачу ResolveNonMSBuildProjectOutput. В старых версиях этой DLL эта задача была .

...