如何以编程方式将自动生成的文件作为Visual Studio中的嵌入式资源?

时间:2015-10-23 02:57:24

标签: c# xml visual-studio embedded-resource

我有一个像这样的复杂工作流:Visual Studio(2013)中的一个项目的构建导致生成XML文件。这些文件由另一个项目使用,作为框架的一部分。

但是,要使XML文件有用,它们将被标记为嵌入式资源 - 目前通过VS UI /表单通过文件属性完成。这适用于手动添加的文件。

但是我如何以编程方式使自动生成的XML文件成为嵌入式资源,以便下一个项目可以选择(在某种意义上)并拥有文件嵌入相应的DLL?

我目前的猜测是以编程方式编辑.csproj文件并添加与下面类似的行:

<EmbeddedResource Include="Path\To\File\MyEmbeddedResource.meta.xml" />
是吗?

1 个答案:

答案 0 :(得分:2)

您可以使用链接项实现此目的 - 如果它们都是同一解决方案的一部分 - 可以使用一组适当的构建依赖项。

首先,构建项目,以便创建要作为资源添加的XML文件。

接下来,在要嵌入XML的项目中,右键单击Solution Explorer中的项目,选择“Add Existing”并浏览XML文件。在点击浏览器中的“添加”按钮之前,单击其右侧的下拉按钮,然后选择“添加为链接”。这将确保文件始终是当前文件。

选择添加的文件链接,并将构建类型更改为“Embedded Resource”。

假设您的XML来自同一解决方案中的项目(如果没有,则忽略此位),然后在Project Dependencies下的解决方案属性中,您可以设置目标项目(资源将在何处)依赖于源项目构建XML文件。

或者,如果您愿意,可以自己添加链接:

<EmbeddedResource Include="Path\To\File\MyEmbeddedResource.meta.xml">
    <Link>MyEmbeddedResource.meta.xml</Link>
</EmbeddedResource>

编辑:讨论后......

如下面的评论中所述,如果您想通过直接操作项目文件来执行此操作,则需要执行以下操作:

  1. 将项目加载为某种Xml文档。

  2. 找到包含项目文件列表的ItemGroup节点,该列表通常是项目中唯一一个包含至少一个Compile节点的节点。

  3. 对于每个文件,插入一个带有可选EmbedResource节点的新Link节点。 Link节点不是必需的,但这是您手动添加链接文件时获得的。

  4. 保存文件。

  5. 似乎相当简单。我的Xml有点生疏,但是这段代码产生了我之后的确切输出:

    // required 'using' directives: System.IO, System.Xml.Linq
    
    public static void EmbedResourceFiles(string projectFilename, IEnumerable<string> fileList, bool makeLinks = true)
    {
        // This is the namespace used by the .csproj Xml file
        XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
        // 1: Open the document
        XDocument project = XDocument.Load(projectFilename);
    
        // 2: Locate target ItemGroup
        var itemGroup = project.Descendants(ns + "Compile").FirstOrDefault()?.Parent;
        if (itemGroup == null)
            throw new Exception("Failed to locate correct ItemGroup node in project file");
    
        // 3: Insert EmbedResource nodes
        foreach (var file in fileList)
        {
            var node = new XElement(ns + "EmbeddedResource", new XAttribute("Include", file));
            if (makeLinks)
                node.Add(new XElement(ns + "Link", Path.GetFileName(file)));
            itemGroup.Add(node);
        }
    
        // 4: Save it, keeping a backup just in case.
        File.Copy(projectFilename, projectFilename + ".bak", true);
        project.Save(projectFilename);
    }
    

    根据需要收集文件列表并将列表传递给上面的方法。如果要禁止创建<Link>节点,请在第三个参数中为其指定“false”。我做了一些测试,似乎没有任何区别。

    希望这可以解决你的问题。