Paraesthesia: .NET Development and Some Pictures of My Cat

Robust File Finding in Your App with MSBuild

I’m working on an application where we wanted to be able to provide some
config or command line parameters that would specify a particular set of
files for processing. What might be considered the “standard” set of
.NET framework libraries comes with
System.IO.Directory.GetFiles(),
but the wildcard support is pretty weak. I don’t want to find *.dll
recursively, I want support like “recursively search folders under this
tree for *.dll but exclude Foo.dll” or something.

So I started thinking - what has that sort of include/exclude support
and robust wildcard matching?

MSBuild.

When you use the
CreateItem
task, you can specify all nature of wildcards, like this:

The ** will be expanded to mean “any number of folders” and the
filename wildcards will work to properly include/exclude files. Way, way
better than GetFiles(). But how do you harness that power for your own
use outside of a build system?

Actually, it turns out to be super easy. Basically:

Add references to the Microsoft.Build.Framework,
Microsoft.Build.Tasks, and Microsoft.Build.Utilities assemblies.
They should be in the GAC.

// Instantiate the taskCreateItemtask=newCreateItem();// Add paths/wildcards to includetask.Include=newITaskItem[]{newTaskItem(@"C:\path\**\*.txt")};// Add paths/wildcards to excludetask.Exclude=newITaskItem[]{newTaskItem(@"C:\path\bin\**\*.*"),newTaskItem(@"**\_svn\**\*.*"),};// Execute the task, check for successboolsuccess=task.Execute();Console.WriteLine("Success: {0}",success);if(!success){return;}// Get the list of matching items from "Include"// and use the "GetMetadata" property to find out the path.foreach(ITaskItemincludeintask.Include){Console.WriteLine("* {0}",include.GetMetadata("FullPath"));}