枚举 .csproj 中的文件(dotnet 核心)

Enumerate Files in a .csproj (dotnet core)

我正在使用 C# 开发一个构建工具,它应该可以与 Visual Studio / MSBuild 一起使用。 我想枚举属于 C# 项目的所有文件。项目格式是新的 (.NET Core).csproj。

描述 Project System 的文档指出使用 MSBuild(文件格式)或通用项目系统(项目树)。我对这两个 API 都不熟悉。查看这些各自项目的文档不会立即有帮助。

正如专家可能知道的那样,新的 .csproj 文件不会列出隐含在项目中的每个文件。另一方面,它可能会列出项目文件夹外的 'linked' 文件。我想确保我获得了所有被视为项目一部分的文件。

最终我想专注于特定文件类型 (.json),但我认为一般问题值得一问。

总结一下:我如何编写一个 C# 库来利用适当的包(希望很容易)枚举 csproj 中的所有文件?

您可以使用 Roslyn 分析器库加载 csproject 并访问它的内容以及程序中的属性。您可以按照 , or use OpenProjectAsync(projectFilePath) 方法中的说明在 Microsoft.CodeAnalysis 命名空间中加载项目 class 的实例。

using Microsoft.CodeAnalysis.MSBuild;

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

您可以在 Github 找到更多关于 roslyn 的信息。

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 链接到相关资源。