Say you had a vast Visual Studio solution of something ridunculous like 120+ projects and wanted to test out a few proofs of concept on improving build times.
Now say that one of the proofs of concept was to use a shared bin folder for all projects in a single solution. Editing 120+ proj files is going to make you a little crazy.
How about a little recursive find-and-replace app using regular expressions (my saviour in many menial text manipulation tasks) to do it all for you? That’d be nice, wouldn’t it? That’s what I thought too. So I just did a quick and dirty console app to do just that.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.IO; using System.Collections.ObjectModel; namespace RecursiveFindAndReplace { class Program { static void Main(string[] args) { // where to start your directory walk var directoryToTraverse = @"C:\VisualStudio2010\Projects\TestSolutionWithLoadsOfProjectsInIt\"; // what files to open var fileTypeToOpen = "*.csproj"; // what to look for var patternToMatch = @"<OutputPath>bin\\[a-zA-Z]*\\</OutputPath>;"; var regExp = new Regex(patternToMatch); // the new content var patternToReplace = @"<OutputPath>;C:\bin\$(Configuration)\</OutputPath>"; // get all the files we want and loop through them foreach (var file in GetFiles(directoryToTraverse, fileTypeToOpen)) { // open, replace, overwrite var contents = File.ReadAllText(file); var newContent = regExp.Replace(contents, patternToReplace); File.WriteAllText(file, newContent); } } // recursive method to return the files we want in all sub dirs of the initial root static List<string> GetFiles(string directoryPath, string extension) { var fileList = new List<string>(); foreach (var subDir in Directory.GetDirectories(directoryPath)) { fileList.AddRange(GetFiles(subDir, extension)); } fileList.AddRange(Directory.GetFiles(directoryPath, extension)); return fileList; } } }
No doubt this could be made prettier with a little lambda, but like I said – quick and dirty.
—————–
Edit: I’ve just realised that Directory.GetFiles is inherently recursive. Duh. So the foreach instead becomes:
// get all the files we want and loop through them foreach (var file in Directory.GetFiles(directoryToTraverse ,fileTypeToOpen ,SearchOption.AllDirectories)) { // open, replace, overwrite var contents = File.ReadAllText(file); var newContent = regExp.Replace(contents, patternToReplace); File.WriteAllText(file, newContent); }
So that’s even quicker and slightly less dirty. Ah well.