johnny 5
johnny 5

Reputation: 21023

MSBuildWorkspace Get Embedded Resource Files

I'm trying to get out all embedded resource files from a solution using Roslyn and MSBuild Api.

private async Task<Document> CheckConstForLocalization(Document document, LocalDeclarationStatementSyntax localDeclaration,
    CancellationToken cancellationToken)
{
    foreach (var project in document.Project.Solution.Projects)
    {
        foreach (var sourceDoc in project.AdditionalDocuments)
        {
            if (false == sourceDoc.Name.EndsWith(".cs"))
            {
                Debug.WriteLine(sourceDoc.Name);
            }
        }

        foreach (var sourceDoc in project.Documents)
        {
            if (false == sourceDoc.Name.EndsWith(".cs"))
            {
                Debug.WriteLine(sourceDoc.Name);
            }
        }
    }

    var newRoot = await document.GetSyntaxRootAsync(cancellationToken);
    // Return document with transformed tree.
    return document.WithSyntaxRoot(newRoot);
}

When I modify my resource files to be AdditionFiles, I can get them through the project AdditionalDocuments. However I would like to be able to grab these with out doing so. The file does not appear in Documents or Additional Documents

How can I find Resx files without modifying their attributes?

Upvotes: 1

Views: 700

Answers (2)

johnny 5
johnny 5

Reputation: 21023

I've figured out a way to find the designer files, I get the associated C# Document names by iterating over the csproj file and getting the embedded resources.

public const string LAST_GENERATED_TAG = "LastGenOutput";
public const string RESX_FILE_EXTENSION = ".resx";
public List<string> GetResourceDesignerInfo(Project project)
{
    XDocument xmldoc = XDocument.Load(project.FilePath);
    XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";

    var resxFiles = new List<string>();
    foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource"))
    {
        string includePath = resource.Attribute("Include").Value;

        var includeExtension = Path.GetExtension(includePath);
        if (0 == string.Compare(includeExtension, RESX_FILE_EXTENSION, StringComparison.OrdinalIgnoreCase))
        {
            var outputTag = resource.Elements(msbuild +  LAST_GENERATED_TAG).FirstOrDefault();

            if (null != outputTag)
            {
                resxFiles.Add(outputTag.Value);
            }
        }
    }

    return resxFiles;
}

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1503220

You can't, at the moment. It isn't supported by the API. (I was researching this just yesterday.)

There's a feature request to support it which you might like to support and subscribe to, but I don't believe there's any way of doing this at the moment.

My understanding is that Visual Studio hooks into MSBuild more tightly than Roslyn's support does at the moment. (See the issue I raised about <Deterministic> for another example.)

Upvotes: 2

Related Questions