Reputation: 9001
I've been doing some work recently that analyzes relationships between various projects in source control. So far I've been using PowerShell and XPath through the Select-Xml cmdlet to process our csproj files, however this relies on my tenuous knowledge of how MSBuild uses the ProjectReference and Reference elements in the project files. It dawned on me that it would be much better if I could use MSBuild itself to resolve the references and then somehow inspect the results of the reference resolution process.
MSBuild experts: does this seem possible? Would this entail writing a custom targets file or something? Would I be forced into also building the projects as well since csproj files also import Microsoft.CSharp.targets?
Any insight would be nice. Thanks!
Upvotes: 0
Views: 1004
Reputation: 9938
It is really quite easy. First reference these assemblies:
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Utilities.v4.0
...and you can create some tooling around the MSBuild object model. I've got a custom MSBuild task that does this analysis right in the build, snippet below:
private bool CheckReferences(string projectFullPath)
{
var project = new Project(projectFullPath);
var items = project.GetItems("Reference");
if (items == null)
return true;
foreach (var item in items)
{
if (item == null)
continue;
if (string.IsNullOrWhiteSpace(item.UnevaluatedInclude))
continue;
if (!item.HasMetadata("HintPath"))
continue;
string include = item.UnevaluatedInclude;
string hintPath = item.GetMetadata("HintPath").UnevaluatedValue;
if (!string.IsNullOrWhiteSpace(hintPath))
if (hintPath.Contains(@"C:\") || hintPath.Contains("C:/"))
LogWarning("Absolute path Reference in project {0}", projectFullPath);
}
return true;
}
Upvotes: 2