Как скомпилировать решение .NET с Roslyn SDK - PullRequest
0 голосов
/ 26 октября 2018

Для многократного (достаточно продвинутого) анализа я хотел бы получить Roslyn SDK: 1. Применяйте диагностику только к «новому» коду (не используйте устаревший код) 2. Обнаружить мертвый код (для общедоступных методов, определения точек входа приложения) 3. Массовое исправление кода

Другими словами: просто создать приложение DiagnosticAnalyzer в пределах Visual Studio недостаточно. Я успешно создал их и написал для них модульные тесты (вдохновленные Sonar ). Тем не менее, это был только анализ одного (или максимум нескольких) файлов за один раз.

Итак, вот моя проблема: я пробовал несколько способов загрузить полное решение .NET и скомпилировать его (себя), но все это не удалось.

public static async Task Main(string[] args)
{
    var analyzers = (new DiagnosticAnalyzer[] { new MyCustomAnalyzer }).ToImmutableArray();

    var file = new FileInfo(@"c:\path\my_solution.sln");

    using (var workspace = MSBuildWorkspace.Create())
    {
        workspace.WorkspaceFailed += OnWorkspaceFailed;

        var solution = await workspace.OpenSolutionAsync(solutionFile.FullName);
        var dependencyGraph = solution.GetProjectDependencyGraph();
        var projectIds = dependencyGraph.GetTopologicallySortedProjects();

        foreach (var projectId in projectIds)
        {
            using (var cancel = new CancellationTokenSource())
            {
                var project = solution.GetProject(projectId);

                var compilation = (await project.GetCompilationAsync(cancel.Token))
                    .WithOptions(project.CompilationOptions)
                    .WithAnalyzers(array, cancellationToken: cancel.Token);

                foreach (var diagnostic in await compilation.GetAllDiagnosticsAsync())
                {
                    (diagnostic.Severity >= DiagnosticSeverity.Error
                        ? Console.Error
                        : Console.Out).WriteLine(diagnostic);
                    // Do magic
                }
            }
        }
    }
}

Это список пакетов, которые я включил:

<PackageReference Include="Microsoft.Build" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.8.166" />
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="2.9.0" />

Я пытался запустить его с .NET core 2.1 и .NET 4.6.1 (как Microsoft.CodeAnalysis.Workspaces.MSBuild - как .NET 4.6.1)

Ошибки, которые я получаю (на основании разных настроек):

.NET 4.6.1

Ошибка Msbuild при обработке файла 'cusotom project.vbproj.or.csproj' с сообщением: C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ MSBuild \ 15.0 \ Bin \ Microsoft. Common.CurrentVersion.targets: (1657, 5): не удалось создать задачу «GetReferenceNearestTargetFrameworkTask» из сборки «C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ Common7 \ IDE \ CommonExtensions \ Microsoft \». NuGet \ NuGet.Build.Tasks.dll». Убедитесь, что сборка задачи была собрана с использованием той же версии сборки Microsoft.Build.Framework, что и на вашем компьютере, и что ваше хост-приложение не пропускает перенаправление привязки для Microsoft.Build.Framework. Невозможно привести объект типа 'NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask' к типу 'Microsoft.Build.Framework.ITask'.

.NET 4.6.1 с MSBUILD_EXE_PATH

Сбой Msbuild при обработке файла cusotom project.vbproj.or.csproj с сообщением: C: \ Program Files (x86) \ MSBuild \ 14.0 \ bin \ Microsoft.Common.CurrentVersion.targets: (1407 , 5): не удалось создать задачу «AssignProjectConfiguration» из сборки «Microsoft.Build.Tasks.Core, версия = 14.0.0.0, культура = нейтральная, PublicKeyToken = b03f5f7f11d50a3a». Убедитесь, что сборка задачи была собрана с использованием той же версии сборки Microsoft.Build.Framework, что и на вашем компьютере, и что ваше хост-приложение не пропускает перенаправление привязки для Microsoft.Build.Framework. Невозможно привести объект типа «Microsoft.Build.Tasks.AssignProjectConfiguration» к типу «Microsoft.Build.Framework.ITask».

.NET Core 2.1

Ошибка Msbuild при обработке файла 'cusotom project.vbproj.or.csproj' с сообщением: импортированный проект "\ bin \ Debug \ netcoreapp2.1 \ Microsoft. .targets" не найден. Убедитесь, что путь в объявлении правильный, и что файл существует на диске. *

.NET Core 2.1 (с MSBUILD_EXE_PATH)

Ошибка Msbuild при обработке файла 'cusotom project.vbproj.or.csproj' с сообщением: Program Files \ dotnet \ sdk .. \ Microsoft.Common.CurrentVersion.targets: (1544, 5): " Не удалось загрузить задачу Microsoft.Build.Tasks.ResolveNonMSBuildProjectOutput "из сборки. Microsoft.Build.Tasks.Core, версия = 15.1.0.0, культура = нейтральная, PublicKeyToken = b03f5f7f11d50a3a. Убедитесь, что объявление правильное, что сборка и все ее зависимости доступны и что задача содержит открытый класс, который реализует Microsoft.Build.Framework.ITask.

То, как я установил путь:

Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", @"Program Files\dotnet\sdk\..\MSBuild.dll");

Я также попробовал истину, поскольку это было предложено где-то, но это ничего не изменило.

1 Ответ

0 голосов
/ 27 марта 2019

Хорошо, поэтому здесь, похоже, есть несколько вещей.

  1. Прежде чем вы сможете вызвать метод MSBuildWorkspace.Create(), его необходимо настроить для использования определенной конфигурации msbuild из вашегоместная машина.Это необходимо для разрешения всех необходимых зависимостей с помощью MEF.Взгляните на описание, которое Дастин Кэмпбелл написал здесь .

    Не включайте никакие Microsoft.Build.* сборки в выходные данные вашего приложения, кроме Microsoft.Build.Locator.Если ваше приложение содержит Microsoft.Build.dll, Microsoft.Build.Framework.dll, Microsoft.Build.Tasks.Core или Microsoft.Build.Utiltiies.Core, они могут мешать обработчику разрешения сборки, установленному MSBuildLocator.

  2. ФактическиЧтобы локализовать экземпляр msbuild на своей машине, вы должны использовать вспомогательный класс MSBuildLocator, который можно найти в пакете Microsoft.MSBuild.Locator nuget (здесь).

  3. В настоящее время весь этот процесс не совсемподдерживается для запуска на ядре dotnet.Они обновили указанный пакет nuget выше, чтобы добавить поддержку ядра dotnet (см. этот выпуск github ) и доступны через предварительный просмотр myget feed .

...