Перечислять файлы в.csproj (ядро dotnet)

Я работаю над инструментом сборки в C#, который должен работать с Visual Studio / MSBuild. Я хочу перечислить все файлы, которые являются частью проекта C#. Формат проекта - новый (.NET Core) .csproj.

Документация, описывающая Систему проектов, указывает на использование MSBuild (формат файла) или Common Project System (дерево проекта). Я не знаком с обоими API. Просмотр документации по соответствующим проектам не сразу полезен.

Как эксперт, вероятно, знает, новый файл.csproj не перечисляет все файлы, которые неявно являются частью проекта. С другой стороны, в нем может быть указан "связанный" файл, который находится за пределами папки проекта. Я хочу убедиться, что я получаю все файлы, которые считаются частью проекта.

В конечном итоге я хочу сосредоточиться на конкретном типе файла (.json), но я подумал, что стоит задать общий вопрос.

Подводя итог: Как я могу написать библиотеку C#, которая использует соответствующие пакеты для (надеюсь, легко) перечислить все файлы в csproj?

2 ответа

Решение

Buildalyzer - самый простой в использовании пакет, он нацелен на.NETStandard 2.0, что делает его кроссплатформенным. (В настоящее время Omnisharp не предлагает пакет NuGet для работы с рабочей областью. А Microsoft.CodeAnalysis создает проблему для получения правильных ссылок на месте и ограничен net46.)

using Buildalyzer;

private static IList<string> InlcudedProjectKeys = new[] { "None", "Compile", "Content", "EmbeddedResource" };

private static IEnumerable<string> EnumerateProjectFiles(string projectPath)
{
    AnalyzerManager manager = new AnalyzerManager();
    ProjectAnalyzer analyzer = manager.GetProject(projectPath);
    AnalyzerResults results = analyzer.Build();
    AnalyzerResult result = results.Single();

    // If only interested in C# files, check out:
    //string[] sourceFiles = result.SourceFiles;

    IReadOnlyDictionary<string, ProjectItem[]> items = result.Items;
    foreach (var item in items)
    {
        // Skip keys like ProjectReference that aren't for files
        if (!InlcudedProjectKeys.Contains(item.Key))
            continue;
        ProjectItem[] projectItems = item.Value;
        foreach (var projectItem in projectItems)
        {
            // The item spec for files will be the path relative to the project directory
            yield return projectItem.ItemSpec;
        }
    }
}

А за бонусные баллы, чтобы получить только *.json файлы:

var jsonFiles = EnumerateProjectFiles(projectPath)
    .Where(path => path.EndsWith(".json"))
    .ToArray();

Спасибо Hitesh Gaur за ссылки на соответствующие ресурсы.

Вы можете использовать Roslyn Analyzer Libraries для загрузки csproject и доступа к его содержимому, а также к свойствам в программе. Вы можете следовать инструкциям из предыдущего поста SO или использовать метод OpenProjectAsync(projectFilePath) для загрузки экземпляра класса Project в пространство имен Microsoft.CodeAnalysis.

using Microsoft.CodeAnalysis.MSBuild;

AnalyzerManager manager = new AnalyzerManager();
ProjectAnalyzer analyzer = manager.GetProject(@"C:\MyCode\MyProject.csproj");

Вы можете найти больше информации о Roslyn на Github.

Другие вопросы по тегам