在C#中读取一个*.CSPROJ文件

35

我正在尝试使用C#编写读取*.CSPROJ文件的代码

我目前的代码如下

   XmlDocument xmldoc = new XmlDocument();
   xmldoc.Load(fullPathName);

   XmlNamespaceManager mgr = new XmlNamespaceManager(xmldoc.NameTable);
   //mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");

   foreach (XmlNode item in xmldoc.SelectNodes("//EmbeddedResource") )
   {
      string test = item.InnerText.ToString();
   }

使用调试器,我可以看到'fullPathName'具有正确的值,并且一旦加载,xmldoc具有正确的内容。

xmldoc没有任何“节点”,就好像内容不被识别为XML一样。

使用XML编辑器,*.csproj文件验证了一个XML文档。

我错在哪里了?


2
请考虑更改此问题的已接受答案。使用MSBuild API本身应该是手动XML处理的首选方法。 - julealgon
3个回答

61

为什么不使用MSBuild API呢?

Project project = new Project();
project.Load(fullPathName);
var embeddedResources =
    from grp in project.ItemGroups.Cast<BuildItemGroup>()
    from item in grp.Cast<BuildItem>()
    where item.Name == "EmbeddedResource"
    select item;

foreach(BuildItem item in embeddedResources)
{
    Console.WriteLine(item.Include); // prints the name of the resource file
}

你需要引用 Microsoft.Build.Engine 程序集。


9
Microsoft.Build.Engine 的 Project 类已被弃用。有没有想法如何使用 Microsoft.Build.Evaluation 中的 Project 类(程序集为Microsoft.Build)实现相同的功能? - Valery Letroye
1
@ValeryLetroye,我没有尝试过,但我认为类似 project.Items.Where(i => i.ItemType == "EmbeddedResource") 这样的代码应该可以工作。 - Thomas Levesque
1
这正是我一直在寻找的!一种很好的方法,可以尊重所有引用的MSBuild目标及其覆盖!从技术角度来看,这应该是更好的解决方案。 - Christopher von Blum
哪个是用于UWP项目的MSBuild API?我无法在任何Windows 10程序集中找到该项目。在应用程序中需要添加任何外部程序集作为引用吗? - Tulika
7
VS2017: Install-Package Microsoft.BuildInstall-Package Microsoft.Build.Utilities.Core这两个命令用于在Visual Studio 2017中安装Microsoft Build工具及其核心实用程序。 - Jay Cummins
显示剩余3条评论

21

你在添加XmlNamespaceManager方面已经接近正确,但是没有在SelectNodes方法中使用它:

XmlNamespaceManager mgr = new XmlNamespaceManager(xmldoc.NameTable);
mgr.AddNamespace("x", "http://schemas.microsoft.com/developer/msbuild/2003");

foreach (XmlNode item in xmldoc.SelectNodes("//x:ProjectGuid", mgr))
{
    string test = item.InnerText.ToString();
}

由于我的项目没有嵌入资源,所以我转而搜索另一个元素。


10

为了完整起见,这里提供XDocument版本,它简化了命名空间管理:

        XDocument xmldoc = XDocument.Load(fullPathName);
        XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";

        foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource"))
        {
            string includePath = resource.Attribute("Include").Value;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接