Reading the list of References from csproj files
Asked Answered
A

3

30

Does anyone know of a way to programmatically read the list of References in a VS2008 csproj file? MSBuild does not appear to support this functionality. I'm trying to read the nodes by loading the csproj file into an XmlDocument but, the XPath search does not return any nodes. I'm using the following code:

System.Xml.XmlDocument projDefinition = new System.Xml.XmlDocument();
        projDefinition.Load(fullProjectPath);

        System.Xml.XPath.XPathNavigator navigator = projDefinition.CreateNavigator();

        System.Xml.XPath.XPathNodeIterator iterator = navigator.Select(@"/Project/ItemGroup");
        while (iterator.MoveNext())
        {
            Console.WriteLine(iterator.Current.Name);
        }

If I can get the list of ItemGroups I can determine whether it contains Reference information or not.

Algolagnia answered 27/7, 2009 at 23:15 Comment(0)
A
49

The XPath should be /Project/ItemGroup/Reference, and you have forgot the namespace. I'd just use XLINQ - dealing with namespaces in XPathNavigator is rather messy. So:

    XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
    XDocument projDefinition = XDocument.Load(fullProjectPath);
    IEnumerable<string> references = projDefinition
        .Element(msbuild + "Project")
        .Elements(msbuild + "ItemGroup")
        .Elements(msbuild + "Reference")
        .Select(refElem => refElem.Value);
    foreach (string reference in references)
    {
        Console.WriteLine(reference);
    }
Ancilla answered 27/7, 2009 at 23:24 Comment(4)
That was much easier. Thanks for the help.Algolagnia
This is great! By now everybody probably noticed it, but just in case -- references could be also made within the solution, in such case you need to get ProjectReference element too.Transcalent
Its very important to not change this line ` XNamespace msbuild = "schemas.microsoft.com/developer/msbuild/2003";` Because I changed it to var by Resharper and afterward I got only problems!Eraser
If you make it "var", the type will be inferred as "string" from the right side. It must be XNamespace, so that the latter's implicit conversion operator from string kicks in.Ancilla
V
11

Building on @Pavel Minaev's answer, this is what worked for me (notice the added .Attributes line to read the Include attribute)

XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
    XDocument projDefinition = XDocument.Load(@"D:\SomeProject.csproj");
    IEnumerable<string> references = projDefinition
        .Element(msbuild + "Project")
        .Elements(msbuild + "ItemGroup")
        .Elements(msbuild + "Reference")
        .Attributes("Include")    // This is where the reference is mentioned       
        .Select(refElem => refElem.Value);
    foreach (string reference in references)
    {
        Console.WriteLine(reference);
    }
Vietnam answered 24/2, 2015 at 11:9 Comment(0)
B
4

Based on @PavelMinaev's answer, I also added the "HintPath" Element to the output. I write the string array "references" to a ".txt" file.

XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
            XDocument projDefinition = XDocument.Load(@"C:\DynamicsFieldsSite.csproj");
            var references = projDefinition
                .Element(msbuild + "Project")
                .Elements(msbuild + "ItemGroup")
                .Elements(msbuild + "Reference")
                .Select(refElem => (refElem.Attribute("Include") == null ? "" : refElem.Attribute("Include").Value) + "\n" + (refElem.Element(msbuild + "HintPath") == null ? "" : refElem.Element(msbuild + "HintPath").Value) + "\n");
            File.WriteAllLines(@"C:\References.txt", references);
Bookmaker answered 5/2, 2016 at 20:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.