Posts Tagged: Source Tree


6
May 10

Retargeting Visual Studio project files with PowerShell

I originally set out to write this post a little over a year ago. Back then I threw together a script to retarget all the project files from .Net 2.0 to .Net 3.5 for my previous company and recently I found myself having to a similar upgrade from .Net 3.5 to 4.0. I ended up using the same script again so I figured I’d go ahead and publish it.

The upgrade process done by Visual Studio on your current projects and solutions will only migrate the file format to the newest schema and will not retarget the framework to the latest version.  That is where the script I’ve included below comes in.  It will retarget all the C# project files found under the path provided to version 4.0 of the .Net framework

C# project files are XML based and navigating the DOM with Linq to XML is a cinch but there are a couple small but important steps that the script needed to include.  First, you need to append the namespace to the individual element names or else the elements will not be able to be found.  Second, when saving the modified XDocument, a XmlWriterSetting instance needs to be instantiated and the OmitXmlDeclaration property set to true.  Setting this property to true will make sure the XML that we save will be considered a valid project file by Visual Studio.

I’ve included the full script below as well as created a gist that can be found here.  It is important to note that this script will edit all the csproj files found under the directory specified in the path variable.  Make sure you backup these files or have them under source control prior to running the script.  Enjoy.

[UPDATE: Added change suggested in comments by Jeffery Snover]

[Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null

#specify the root of your source tree below
$path = "C:\Code\chatsworth"

$ns = "http://schemas.microsoft.com/developer/msbuild/2003"
$xname = [System.Xml.Linq.XName]::Get("PropertyGroup",$ns)
$tfname = [System.Xml.Linq.XName]::Get("TargetFrameworkVersion",$ns)

$xws = New-Object System.Xml.XmlWriterSettings
$xws.OmitXmlDeclaration = $true
$xws.Indent = $true

function updatefx($filename)
{
    #Write-Host $filename
    $xml = [System.Xml.Linq.XDocument]::Load($filename)

     $result = $xml.Descendants($xname)

    foreach ($i in $result)
    {
        $fxelem = $i.Element($tfname)
        if($fxelem)
        {
            $i.SetElementValue($tfname,"v4.0")
        }
    }

    $xw = [System.Xml.XmlWriter]::Create($filename, $xws)
    $xml.Save($xw)
    $xw.Close()
}

$csprojs = Get-ChildItem $path *.csproj -Recurse

foreach ($file in $csprojs)
{
    updatefx $file.FullName
}


7
Mar 09

Tree Surgeon: Review and a couple tips

This past week I was playing around with Hudson and Team City and getting some NAnt scripts put together to use.  In a happy coincidence I happened to catch a mention about Tree Surgeon from twitter and it had piqued my curiosity.  Tree Surgeon is a project on CodePlex that has been around for a while and helps automate the process of setting up a source tree and assembling build scripts.  It was just what I was looking for.

The goal of Tree Surgeon was to make setting up and laying out new projects using best practices dead simple.  All the major tools and libraries that typically find their way into your .Net source trees are provided for you.  In addition to laying out the directory structure for your source and libraries, a solution file gets created with three main projects to get you started.  The basic project setup includes a console app, core library and unit test project.  The build scripts come pre-wired to have NCover run your tests and generate reports from the results and also do things like packaging your build artifacts into zip files for deployment.

The whole process, start to project generated, is very easy.  Download and run the installer.  Launch the program, select the version of Visual Studio (2003, 2005, and 2008) and the flavor of testing framework (NUnit or MbUnit) and then hit generate.  The files and directories, built out in your Documents folder, are then created and ready to be used.

There are two slight issues I ran into that I’d like to point out.  Both issues had already been noted in the project forums and were easy to fix.  When generating a source tree with MbUnit selected as the unit test framework, the build script generated has the unit test assembly referenced is named incorrectly.  You will have to change it to match your project’s unit test assembly name.  The second issue has to do with running NCover and NUnit on x64 machines.  I found that in order for NCover and NUnit to work on x64 machines I had to add two calls to the CorFlags utility to make executables work.  This was accomplished by making the modifications to the ‘run-unit-tests’ target below on lines 5-8.

   1: <target name="run-unit-tests">
   2:     <mkdir dir="${build.dir}\test-reports" />
   3:     <exec program="regsvr32" workingdir="tools\NCover" commandline="/s CoverLib.dll" />
   4:     <!-- Need the CorFlags Commands For x64 -->
   5:     <exec program="C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\CorFlags" 
   6:         workingdir="tools\NCover" commandline="NCover.Console.exe /32BIT+" />
   7:     <exec program="c:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\CorFlags" 
   8:         workingdir="tools\NUnit" commandline="NUnit-Console.Exe /32BIT+" />
   9:     <exec program="tools\ncover\NCover.Console.exe" 
  10:         workingdir="${build.dir}\Debug\UnitTests">
  11:         <arg value="//w &quot;.&quot;" />
  12:         <arg value="//x &quot;..\..\test-reports\Coverage.xml&quot;" />
  13:         <arg value="&quot;..\..\..\tools\nunit\nunit-console.exe&quot;" />
  14:         <arg value="&quot;MyProjectName.UnitTests.dll&quot; 
  15:             &quot;/xml:..\..\test-reports\UnitTests.xml&quot; &quot;/nologo&quot;" />
  16:     </exec>
  17: </target>

Even though I am pretty late to the party with Tree Surgeon I am very happy to have stumbled across it.  The whole source tree and build script setup process is the perfect thing to script out and I am really glad the project creator and contributors have taken the time to do this.  It is a big help and I highly recommend you try it out the next time you are spinning up a new source tree for a project.