Friday, January 2, 2009

Editing multiple VS2008 solution files with PowerShell

Our huge LOB application is comprised of 30+ Visual Studio 2008 projects. One of these projects, which I'll call the 'Framework', is used as a reference by many of the projects. We use several different solution files comprised of a subset of the 30+ projects in order to improve Visual Studio performance as well as reduce Solution Explorer visual clutter.

I recently needed to move the Framework project to a new location in Team Foundation Version Control (TFVC). This move meant that some of the solution files needed to be altered because the TFVC references inside the file would now be invalid. Specifically, the SccProjectNameNN reference needed to be altered, where NN is the ordinal value of the project reference in the solution file.

Doing this in Visual Studio would be extremely tedious because each solution file would have to be opened, remove the invalid Framework project(which would also cause the reference to be automatically removed from the other projects in the solution), add the valid Framework project reference back to the solution, and add the Framework project reference back to each affected project. Time was also a factor. I didn't want to hold up developers by having solution and project files checked out. We allow shared checkouts, but I was concerned about developer TFS workspaces if I made any mistakes.

Recently I had used Powershell to alter reference paths in a Visual Studio project file. Could I do the same with the solution files? (Hint: Yes, I could.)

PS H:\> $projectLocation = "C:\Workspace"
PS H:\> $files = get-childitem $projectLocation -include *.*sln -recurse
| Select-String -pattern "/OldVersionControl" -SimpleMatch
| Select-Object -Property Path
PS H:\> $files | Foreach-Object { CheckOutTfsFile( $_.Path) }
PS H:\> $match = "/OldVersionControl"
PS H:\> $replacement = "/NewVersionControl"
PS H:\> $files
| Foreach-Object { (Get-Content -Path $_.Path -encoding UTF8 )
-replace $match, $replacement | Set-Content $_.Path -encoding UTF8 }

As you can see there's no real magic here- just a simple replace operation inside each file that has content that matches '/OldVersionControl'. The pipeline allowed me to avoid the dreaded manual tediousness of updating multiple solution files.

No comments:

Post a Comment