• 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")
            $_.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
    # 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
    $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"

  • Visual Studio network performance with TFS through a VPN

    I’ve been accessing a TFS server remotely through a VPN connection. I’d noticed that the performance was not that great, and then discovered this suggestion to specify the defaultProxy element in the devenv.exe.config file.

    That worked pretty well, but I noticed that things were still a bit sluggish, so added a bypasslist element too, to ensure that anything on a network doesn’t use the proxy either. That’s working nicely now.

    <?xml version=”1.0” encoding=”utf-8”?>

                       <proxy bypassonlocal="True" proxyaddress=[http://proxy-server:8888](http://proxy-server:8888)/>