How to find References in a C# Project File (.csproj) using LINQ (Xml)

I was asked to “Generate a report of all our c# projects and their dependencies.

:<

So instead of going through 333+ csprojs manually, it was time to write a helper routine to look through the .csproj xml.

And instead of old-school XPath and SelectNodes() (boooo), it was time to write some Linqy-Dinq.

The below code will query a csproj file and report back all all project references. 

It will report back:

(1) If the reference is an already compiled dll.  Not in the GAC.
(2) If the reference is an already compiled dll.  In the GAC.
(3) If the reference is a reference “by project”.

Feel free to post any suggestions and/or improvements.

The biggest trick was adding the namespace to the conditional clauses. ( ns + “SomeElementName” ).
The other trick was figuring out how to ignore Xml-Element(s) if there was no value.
Oh, it is so simple when it is done.  But took a while to figure out the nuances.

//using System.Xml.Linq;

string fileName = @”C:\MyFolder\MyProjectFile.csproj”;

XDocument xDoc = XDocument.Load(fileName);

XNamespace ns = XNamespace.Get(http://schemas.microsoft.com/developer/msbuild/2003&#8221;);


//References “By DLL (file)”

var list1 = from list in xDoc.Descendants(ns + “ItemGroup”)
from item in list.Elements(ns + “Reference”)

/* where item.Element(ns + “HintPath”) != null */ /* optional */

select new
{
CsProjFileName = fileName,
ReferenceInclude = item.Attribute(“Include”).Value,
RefType = (item.Element(ns + “HintPath”) == null) ? “CompiledDLLInGac” : “CompiledDLL”,
 HintPath = (item.Element(ns + “HintPath”) == null) ? string.Empty : item.Element(ns + “HintPath”).Value};

foreach  (var v in list1)
{
    Console.WriteLine(v.ToString());
}

//References “By Project”
var list2 = from list in xDoc.Descendants(ns + “ItemGroup”)
from item in list.Elements(ns + “ProjectReference”)

where
item.Element(ns + “Project”) != null

select new
{
CsProjFileName = fileName,
ReferenceInclude = item.Attribute(“Include”).Value,
RefType = “ProjectReference”,
ProjectGuid = item.Element(ns + “Project”).Value
};

foreach (var v in list2)
{
    Console.WriteLine(v.ToString());
}

Posts that helped me:

http://stackoverflow.com/questions/2338512/understanding-linq-to-xml-descendants-return-no-results

http://stackoverflow.com/questions/2630192/c-sharp-check-an-element-exists-while-using-linq-to-xml

Bonus Code:

string startFolder = @”C:\DotNetCodeBase\”;

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(startFolder);

IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles(“*.csproj”, System.IO.SearchOption.AllDirectories);

IEnumerable<System.IO.FileInfo> fileQuery = from file in fileList
    where file.Extension == “.csproj”
    orderby file.Name
select file;

 

This entry was posted in Software Development. Bookmark the permalink.

3 Responses to How to find References in a C# Project File (.csproj) using LINQ (Xml)

  1. jb says:

    the code looks good – i’m going to try it…
    Thankyou

  2. Great! any updates about it in 2014 ? Thanks.

  3. Sai karthik says:

    Very Useful post.

Leave a comment