Enumerate Files in a .csproj (dotnet core)

心不动则不痛 提交于 2019-12-11 16:56:21

问题


I am working on a build tool in C# that should work with Visual Studio / MSBuild. I want to enumerate all files that are part of a C# project. The project format is the new (.NET Core) .csproj.

The documentation describing the Project System points at using MSBuild (file format) or Common Project System (project tree). I'm unfamiliar with both APIs. Looking at documentation for those respective projects is not immediately helpful.

As the expert probably knows, the new .csproj file does not list every file that is implicitly part of the project. On the other hand it may list a 'linked' file that is outside the project folder. I want to make sure I get all files that are considered part of the project.

Ultimately I want to focus on a particular file type (.json), but I thought the general question was worth asking.

To sum up: How can I write a C# library that leverages the appropriate packages to (hopefully easily) enumerate all the files in a csproj?


回答1:


You can use Roslyn Analyzer Libraries to load csproject and access it's content as well as properties in program. you can follow instructions from this previous SO post, or use OpenProjectAsync(projectFilePath) method to load instance of Project class in Microsoft.CodeAnalysis namespace.

using Microsoft.CodeAnalysis.MSBuild;

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

You can find more information on roslyn at Github.




回答2:


Buildalyzer is the easiest package to use, and it targets .NETStandard 2.0 making it cross-platform. (Omnisharp does not currently offer a NuGet package for working with the workspace. And Microsoft.CodeAnalysis poses a challenge to get the correct references in place, and is limited to 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;
        }
    }
}

And for bonus points, to get only *.json files:

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

Thanks Hitesh for linking to relevant resources.



来源:https://stackoverflow.com/questions/53070977/enumerate-files-in-a-csproj-dotnet-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!