• DDD Adelaide 2011

    Mark this in your diaries – the “DeveloperDeveloperDeveloper Adelaide” conference or (“DDD Adelaide” for short) is going to be on Saturday July 16th.

    Following in the footsteps of DDD Melbourne and DDD Sydney, we hope that the Adelaide event will mirror their success!

    Suggestions for speakers and session topics are currently being accepted (Go to www.dddadelaide.com for details), then following the DDD model, the list of topics will be available to vote on to decide the final list.

    It will be held at UniSA’s City West Campus.

    Finally, an case you were wondering this is the successor to CodeCampSA.

  • Turn on "Warnings as Errors" for all projects in a solution

    It’s a habit of mine to always try to address any compiler warnings, as more often than not a warning is an indication that something is wrong with your code (even though it is still may be compilable). One way to ensure this is to make warnings cause a build to fail (just like errors do).

    For a single project, you can turn this on within the Build tab of the Project Properties page:

    Treat warnings as errors in Project Properties

    If you have a large solution with lots of existing projects, this can be a bit tedious so I wrote a PowerShell script to automate the process. It finds all C# projects, and for each .csproj file updates every configuration block found and adds a new TreatWarningsAsErrors element. (If you don’t use TFS then just comment out the line that calls TF.EXE)

     Get-ChildItem -Recurse -Filter "*.*csproj" | % {
        Write-Host $_.Name
    
        $filename = $_.Fullname
    
        $proj = [xml]( Get-Content $_.Fullname )
    
        $xmlNameSpace = new-object System.Xml.XmlNamespaceManager($proj.NameTable)
    
        $xmlNameSpace.AddNamespace("p", "http://schemas.microsoft.com/developer/msbuild/2003")
    
        $nodes = $proj.SelectNodes("/p:Project/p:PropertyGroup[@Condition and not (p:TreatWarningsAsErrors)]", $xmlNameSpace)
    
        $touched = $false
    
        $nodes | ForEach-Object -Process {
            $e = $proj.CreateElement("TreatWarningsAsErrors", "http://schemas.microsoft.com/developer/msbuild/2003")
            $e.set_InnerText("true")
            $_.AppendChild($e) | Out-Null
            $touched = $true
        }
    
        if ($touched) {
            Write-Host "Checkout $filename"
            & "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe" checkout $filename | Out-Null
    
            $proj.Save("$($filename)") | Out-Null
        }
    }
    

  • Checking build durations over time

    I’ve written a PowerShell script to iteratively grab changesets from TFS, and do a build of the solution from that changeset. For each build I record the time taken. This is useful if you think builds are taking longer than they used to and you need some quantitative evidence. You can save the output to a CSV file and open it up in Excel to display a pretty graph etc.

    To use the script, you’ll need to have installed the Team Foundation Server Power Tools which include PowerShell cmdlets for TFS.

    \# Iteratively build changesets from TFS to measure build speed
    #
    # Run this from a folder that is mapped as the TFS workspace
    
    # Load VSVARS.BAT (From http://blogs.msdn.com/b/ploeh/archive/2008/04/09/visualstudio2008powershell.aspx)
    function VsVars32()
    {
        $vs100comntools = (Get-ChildItem env:VS100COMNTOOLS).Value
        $batchFile = \[System.IO.Path\]::Combine($vs100comntools, "vsvars32.bat")
        Get-Batchfile $BatchFile
    }
    
    function Get-Batchfile ($file) {
        $cmd = "\`"$file\`" & set"
        cmd /c $cmd | Foreach-Object {
            $p, $v = $\_.split('=')
            Set-Item -path env:$p -value $v
        }
    }
    
    VsVars32
    
    # Get changeset history since 1-Jan-2011 and checked in by me
    $history = Get-TfsItemHistory "$/Project/Branch" -Version "D01/01/11~" -Recurse | Where-Object { $\_.Owner -eq "DOMAIN\\username" }
    
    # Process changesets from earliest to latest
    \[array\]::Reverse($history)
    
    $tf = "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\TF.exe"
    
    $history | % {
        & $tf get /version:C$($\_.ChangesetId) /Recursive /Overwrite /NoPrompt 2>&1 | Out-Null
    
        # clean first
        & "msbuild.exe" /t:Clean /noconlog /v:q /nologo 2>&1 | Out-Null
    
        # build
        $duration = Measure-Command { & "msbuild.exe" /noconlog /v:q /nologo  }
    
        if ($LastExitCode -eq 0)
        {
            Write-Output "$($\_.ChangesetId), $($duration.TotalSeconds)"
        }
        else {
            Write-Warning "$($\_.ChangesetId) build failed"
        }
    }