Browsing Posts in .NET Tools

imageSystem.Type and XML are the nuts and gum of the development world. You can stuff a System.Type into an XML file, but it leaves a bad taste in your mouth. Sometimes you don’t have much choice. For example:

  • Custom configuration sections in App.config/Web.config
  • Handlers and modules in Web.config
  • ProxyFactoryFactory, 2nd-level cache provider, database dialect, and other pieces of configuration in hibernate.cfg.xml*
  • XML-based IoC configuration**

* NHibernate Loquacious configuration is now a better option for configuring NHibernate IMHO and I use it in all my new apps rather than hibernate.cfg.xml.

** For IoC containers, convention-over-configuration is a better choice followed by code-based configuration. I use XML-based configuration only as a last resort, but it can sometimes be useful for configurable overrides.

When you do need to encode a System.Type into a XML file, JetBrains ReSharper makes your life a lot easier. (This is a little-known feature of ReSharper shown to me by Ilya “Orangy” Ryzhenkov, ReSharper Product Manager.) I decided to create a completely silly, contrived example where we need to display a list of hot peppers and their Scoville heat units and the information is stored in App.config. (Yes, I know. A database or flat file would be a better place. I told you that it was a contrived example.) I have created a PeppersConfigurationSection class that is defines the <peppers> configuration section. I need to specify the type name in the <configurationSections> where it says <INSERT_TYPE_NAME_HERE>

<?xml version="1.0" encoding="utf-8" ?>
    <section name="peppers" type="<INSERT_TYPE_NAME_HERE>" />
    <pepper name="Crazy Jerry's Brain Damage" scovilles="11000" type="sauce"/>
    <!-- more peppers -->

Rather than typing out the namespace-qualified type name, I simply type PCS for PeppersConfigurationSection and press ReSharper’s Import Symbol Completion (IDEA: CTRL-ALT-Space; VS: ALT-SHIFT-Space).

Import Type Completion

You can see the normal ReSharper completion pop-up appear. Selecting the first one, I get:

Type Completed

This is fine and dandy if the custom configuration section is defined in your project, but what if you need to specify the assembly name too? ReSharper once again comes to our rescue with a Quick Fix (ALT-Enter).

Add module qualification

Selecting the Add module qualitication Quick Fix and we end up with this. (I added linebreaks between the parts of the fully qualified type name for ease of readability in the screenshot.)


Add module qualification is even handier if the assembly has a public key token as those are a hassle to look up. Once again, ReSharper does the hard work of inserting the type name – I only typed NVSH CTRL-ALT-Space – and then the quick fix to get the qualification with assembly name, version, culture, and public key token:


I hope this little ReSharper gem makes your coding lives just a little bit easier…

N.B. ReSharper 5.1 and 6.0 EAP (up to at least build 2136) has a bug that causes Import Symbol Completion to fail for files named Web.config in a ASP.NET project. If you rename Web.config to Foo.config – no other changes necessary – you can use Import Symbol Completion. Just remember to rename the file back to Web.config when you’re done. Another option is to copy Web.config to another project type (Console and Class Library both work), make your changes, and then copy back. I have reported the issue to JetBrains here and the team is working on a fix.

We’ve all done it at one point or another. Our application throws an exception and we start wading through a standard Windows error dialog or a log file to examine the exception and stack trace. If you’re a ReSharper Jedi, you’ve probably copied the exception and stack trace to the clipboard and hit CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) in Visual Studio to launch ReSharper’s Stack Trace Explorer. (If you have’t, you’ll see the Stack Trace Explorer in just a second.)

Let me show you an easier way that works well on desktop or Silverlight apps. I’ll use Silverlight for demo purposes, but the same technique works with WPF and WinForms. First we need to hook up a global error handler:

public MainPage() {
    Application.Current.UnhandledException += HandleApplicationUnhandledException;

private static void HandleApplicationUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) {
    if(Debugger.IsAttached) {
    e.Handled = false;

Please note that this is demo code and I’m simply hooking this up in the code behind. In a larger application, I would typically publish an ErrorOccurred message to my application’s message bus and register a listener that would contain the code in HandleApplicationUnhandledException.

Notice that I’m checking whether a debugger is attached. If so, I place the contents of the System.Exception (or derived exception) on the clipboard. (Clipboard is in the System.Windows namespace for Silverlight and WPF apps, but there is an identically-named class in System.Windows.Forms.) The reason that I’m checking whether a debugger is attached is so that end-users don’t get the clipboards spammed with exception text. You could conditionally compile the code so that production builds don’t contain it, but personally I like having the code in production too. It means that I can grab an old build, attach a debugger, and get the same exceptions that the end users are getting.

Now that the exception and stack trace is on the clipboard, I jump over to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS). I am immediately presented with ReSharper’s Stack Trace Explorer as ReSharper is smart enough to grab the current clipboard contents to display:


The advantage here is fictionless debugging as you no longer have to find, select, and copy the exception and stack trace to the clipboard. It’s there for you automatically. As soon as you hit an exception, simply jump to Visual Studio and press CTRL-SHIFT-E (IDEA) or CTRL-E, T (VS) and you’re ready to find the problem. Also note that all the method names in the ReSharper’s Stack Trace Explorer are hot links to the appropriate code file allowing for easy navigation of your code base, the .NET Framework, and third-party libraries.

One quick note regarding Silverlight… Many modern browsers (e.g. FF4, IE8+, Chrome, …) will run Silverlight in a separate process. So even when you launch with debugging (F5), you’ll be attached to the browser process itself and not the child process that is hosting Silverlight. To correct this, simply go to Debug… Attach to Process… and find the hosting process where the type is Silverlight. (For FireFox 4, the hosting process is called plugin-container.exe. For IE8+ and Chrome, the hosting process is called iexplore.exe or chrome.exe, respectively. Just look for the one hosting Silverlight as noted under the “Type” column.)


Happy Debugging!

psake It is with great pleasure that I announce psake v4.00, which you can download here. The project has grown up a great deal in the last few months. More projects are using psake for orchestrating their builds and we have more developers submitting patches. I’m really pleased with how psake is growing up. GitHub has become our coordination point for the project, which you can find here, and we will be retiring the Google Code site. Jorge has started work on a FAQ, which will make it easier for developers to get started with psake. Look for it on the GitHub wiki in the next few weeks.

What’s new in psake v4.00?

  • Exec helper function
  • .NET 4.0 support
  • 64-bit support
  • psake.ps1 helper script
  • Support for parameters & properties
  • Support for nested builds
  • Tab expansion
  • Invoke default script
  • Various minor bug fixes

Exec Helper Function

The exec helper function was included in the psake v2.02 patch, but it bears mentioning again. If you are executing a command line program (such as msbuild.exe, aspnet_compiler.exe, pskill.exe, …) rather than a PowerShell function, it will not throw an execption on failure, but return a non-zero error code. We added the exec helper function, which takes care of checking the error code and throwing an exception for command line executables.

task Compile -depends Clean {
  exec { msbuild Foo.sln }

You can find out more details here.

.NET 4.0 Support

psake still defaults to .NET Framework 3.5, but you can specify another framework to use from the command line:

invoke-psake examples\default.ps1 -framework 4.0

Or from within your script:

$framework = '4.0'

task default -depends MsBuild

task MsBuild {
  exec { msbuild /version }

64-bit Support

You can now specify whether you want to use 32-bit (x86) or 64-bit (x64) tools when building your projects.

invoke-psake examples\default.ps1 -framework 3.5x86
invoke-psake examples\default.ps1 -framework 3.5x64

If you don’t specify x86 or x64 after the framework version, psake selects the framework bitness based on whether you’re running from a 32-bit or 64-bit PowerShell prompt. (On 64-bit Windows, the default PowerShell prompt is 64-bit. If you want a 32-bit prompt, launch “Windows PowerShell (x86)”. Valid values for the framework are ’1.0′, ’1.1′, ’2.0′, ’2.0×86′, ’2.0×64′, ’3.0′, ’3.0×86′, ’3.0×64′, ’3.5′, ’3.5×86′, ’3.5×64′, ’4.0′, ’4.0×86′, and ’4.0×64′.

psake.ps1 Helper Script

Because psake is a PowerShell module, you have to import the module before using it.

import-module .\psake.psm1
invoke-psake examples\default.ps1
# do some work
invoke-psake examples\default.ps1
# do some more work
remove-module psake # when done, remove psake or close your PS prompt

If you want to use the psake.psm1 stored in a particular project’s repository, you have to remember to import the correct version of psake from that project. You also need to create a ps1, bat, or cmd file for your continuous integration server so that the correct version of psake is registered to orchestrate the build. We have standardized this using a psake.ps1 helper script:

# psake.ps1
# Helper script for those who want to run
# psake without importing the module.
import-module .\psake.psm1
invoke-psake @args
remove-module psake

With this script, you can now execute psake without first importing the module.

.\psake examples\default.ps1 test

You can read about the splatting operator (@) here if you’re wondering what invoke-psake @args does.

Support for Parameters and Properties

Invoke-psake has two new options, –parameters and –properties. Parameters is a hashtable passed into the current build script. These parameters are processed before any ‘Properties’ functions in your build scripts, which means you can use them from within your Properties.

invoke-psake Deploy.ps1 -parameters @{server=’Server01’}

# Deploy.ps1
properties {
  $serverToDeployTo = $server

task default -depends All

# additional tasks

Parameters are great when you have required information. Properties on the other hand are used to override default values.

invoke-psake Build.ps1 -properties @{config='Release'}

# Build.ps1
properties {
  $config = 'Debug'

task default -depends All

# additional tasks

Support for Nested Builds

You can now invoke build scripts from within other build scripts. This allows you to break large, complex scripts into smaller, more manageable ones.

task default -depends RunNested1, RunNested2

task RunNested1 {
  Invoke-psake .\nested\nested1.ps1

task RunNested2 {
  Invoke-psake .\nested\nested2.ps1

Tab Expansion

Dusty Candland implemented PowerShell tab expansion for psake. You can find instructions on setting up tab expansion in ./tabexpansion/Readme.PsakeTab.txt in the download. Once configured, you can:

tab completion for file name: psake d<tab> -> psake .\default.ps1
tab completion for parameters: psake -t<tab> -> psake -task
tab completion for tasks: psake -task c<tab> -> psake -task Clean

You can find more details on Dusty’s blog here. Excellent addition! Thanks, Dusty.

Invoke Default Script

Jason Jarrett provided this welcome fix, which allows you to execute tasks without specifying the default build file name (default.ps1).

invoke-psake Compile # Executes the Compile task in default.ps1

Previously you had to specify invoke-psake default.ps1 Compile. You could only omit default.ps1 if you were running the default task.

Big Thanks!

Thanks to everyone who contributed to this release, especially Jorge Matos who contributed many of the new features noted above. If you have any questions, please join the psake-users Google Group. If you’re interested in contributing to the ongoing development, we also have a psake-dev Google Group. Happy scripting, everyone!

P.S. Wondering what happened to psake v3.00? It’s chilling with its friends EF v2 and EF v3…


A few announcements… First the big one. Many people have been using psake – both the PowerShell 1.0- and 2.0-compatible versions – in production without any significant issues. For that reason, we have released psake v1.00 (compatible with PowerShell 1.0). The only difference between psake v1.00 and psake v0.23 is the version number. My friend, Ayende, has a great example of converting Rhino Mocks build to use psake.

We have released psake v2.01 (compatible with PowerShell 2.0). (This was formerly called psake v0.24, “Jorge”, and psake-ps2.) A big thanks to Jorge Matos for all his work on psake v2.01.

A few minor changes… The source code for psake has been moved to GitHub and the SVN repository at Google Code has been retired. We will still be using Google Code for bug tracking, wiki pages, etc. If you want the latest source code, you can always download a zip file for master (aka trunk in SVN terms) – or any tags/branches – from:

Note that there is no need to install Git to download the latest package as GitHub will create the appropriate zip file on the fly.

If you have some great idea, you can download the git repo from git:// or (msysgit is the Git package of choice for Windows. You can download it from I would encourage you to read Jeremy Skinner’s excellent guide for contributing to MvcContrib via GitHub. Just mentally replace “MvcContrib” with “psake”, though I’d encourage you to contribute to MvcContrib too. :)

I would like to offer lots of kudos to my collaborators/conspirators on the project. Jorge Matos has been instrumental in updating/improving psake to use the new PowerShell v2 features. Thanks to Shaun Becker for patches and answering newsgroup questions. And thanks to Eric Hexter for his assistance in moderating the psake-users Google Group. I am heartened and thankful for the willing collaboration on this project and am excited to watch it grow. If you have any questions, please do not hesitate to ask.

Going forward, we are retiring psake v1.00 and focusing on psake v2.00. If there is demand for a PowerShell v1-compatible version of psake, we will create a branch based on the v1.00 tag, but we will mostly be focused on the PowerShell v2-compatible version (aka psake v2.00). So your next question probably is…

What’s New in psake v2.01?

(from Jorge Matos)

The main difference is that psake v2.01 has been re-written as a module that contains advanced functions.  Someone using the module could either run the import-module command with the path to the module file (i.e. import-module .\psake.psm1) or (my preference) you can copy the psake.psm1 into a folder called psake into the “Modules” folder in your profile directory (you may have to create it if it’s not there) or your machine-wide “Modules” directory:

i.e. Profile Directory:


i.e. Machine-wide Modules folder:


Once the psake folder is created and you’ve copied the psake.psm1 file into it – restart PS and type “import-module psake” – PS will find the module and load it automatically.  What I’ve done is add the “Import-Module psake” to my profile script so that it is loaded everytime I startup PS.

Module Benefits:
  1. Build scripts don’t need to know where psake is installed, they just call Invoke-psake and it works.
  2. Encapsulation… Global variables are no longer required since they can be private to a module unless explicitly exported (I haven’t gotten around to actually changing the psake code to not use global variables yet).
  3. Modules can be unloaded if needed which removes all the code and variables from memory.
Advanced Functions:

The other big difference is that the “Invoke-psake” and “Task” functions have been converted into Advanced Functions which basically means you can take advantage of comment help which means you can type help invoke-psake and you will get back real help with examples.

Minor changes:
  1. Coding style is different.
  2. Try/Catch is used instead of the “Trap” statement.
  3. Got rid of the “exec” function.
  4. You can now define “Pre” and “Post” actions for a task.
  5. You can define how the task name will be formatted.
  6. You can define a “TaskSetup” function that will be executed before every task (took that from NUnit).
  7. You can define a “TaskTearDown” function that will be executed after every task (took that from NUnit too).
  8. Create a global variable called “psake_buildSucceeded” that will be set to true if the build succeeds – scripts can check this.
  9. Also added a “$noexit” switch to Run-Psake so that the function will not use the exit() function so that you can test a build script at the command line without PS closing down (the default behavior when the build fails is to call exit(1) so that the calling code can determine if the build failed or not).
  10. The psake-buildTester.ps1 had to be changed slightly in order for it to call the Invoke-psake function.
  11. Added more examples in the .\examples folder for POST conditions, PRE and POST Actions, etc.

Happy (build) scripting!

Visual Studio 2008 SP1 and ReSharper 4.1 were happily running and helping me develop software, but I wanted to try out the early drops of ReSharper 4.5, which you can find here. I didn’t want to disturb my existing install. So I went looking for a way to run ReSharper 4.1 and 4.5 side-by-side. JetBrains provides the following installation notes, which gave a glimmer of hope.

Let me start off by saying that I don’t have any meaningful experience building add-ins for Visual Studio. Everything below was gleaned from JetBrains and MSDN documents. Having gone through the trouble, I wouldn’t recommend this approach due to certain – apparently inherent – limitations. (The biggest limitation is that you can only run Visual Studio from the experimental hive as an administrator. The RANU switches might give you a glimmer of hope, but JetBrains would have to update its install utility to support it, as far as I can tell.)

Honestly, turn back now! It’s not worth the trouble. If you’re really concerned about the cleanliness of your Visual Studio install, I would recommend installing VS2008 and ReSharper 4.5 in a virtual machine. If not, then I would recommend uninstalling ReSharper 4.1, installing ReSharper 4.5, and tolerating any glitches in the early builds. The occasional glitch is probably going to be less annoying than the instructions below!

Remember: ReSharper 4.5 builds are daily builds of a product that is in active development. JetBrains is very upfront about the quality of builds on their daily builds page. Whichever method you choose – experimental hive or regular install – be prepared to upgrade to a later build on at least a weekly or biweekly basis.

Oh, you’re still here. I guess you really want to know about how to install ReSharper into an experimental Visual Studio hive. Don’t say I didn’t warn you.

Let’s take a journey into the black art of Visual Studio add-in development… If you’re developing an add-in for Visual Studio, how the heck do you develop and debug it safely. How do you develop in one copy of Visual Studio and use it to debug another copy of Visual Studio running your plug-in? You use experimental Visual Studio hives. Visual Studio hives are areas of the Windows registry that Visual Studio uses to store configuration information. Visual Studio uses the key HKLM\SOFTWARE\[Wow6432Node]\Microsoft\VisualStudio\9.0 to store its default hive. (If you’re running 64-bit Windows, configuration information is stored beneath the Wow6432Node because Visual Studio 2008 is a 32-bit program. If you’re running 32-bit Windows, the registry path doesn’t contain the Wow6432Node.) If you install into an experimental hive, a suffix is appended to the registry path. For example, we’ll be using an experimental hive called ReSharper. So the registry path is HKLM\SOFTWARE\[Wow6432Node]\Microsoft\VisualStudio\9.0ReSharper. When you launch Visual Studio, you can direct it to the default hive (launch VS normally) or an experimental hive via:

devenv /RootSuffix ReSharper

You can have as many experimental hives as you like. This leaves you free to try out different add-ins, ReSharper or otherwise, in a relatively isolated fashion. The choice of “ReSharper” as my experimental hive name is completely arbitrary. I could just as easily called it Ickyickyickyickypatangzoopboing. (Bonus points if you can place the experimental hive name.) :)

Please note that you’ll be mucking around with your registry and in particular, your Visual Studio install. If things go really badly, you could have to re-install Visual Studio or even your OS. Probably not, but this is an unsupported install mode. Use the same care as directly editing your Windows Registry (which is essentially what you’re doing). I’m not responsible for any damage you may cause. No warranty express or implied. Do not wash in hot. Objects in mirror may be closer than they appear… smile_regular

You’ll need to download the Visual Studio 2008 SDK 1.1 – the version of the SDK for Visual Studio 2008 SP1. (It would have been too easy to call it the Visual Studio 2008 SP1 SDK.) You can find it here. The SDK contains tools for managing experimental Visual Studio hives. The one that we’ll need is called VsRegEx, which is a command line tool for creating, modifying, and deleting experimental Visual Studio hives. We’ll be creating an experimental hive called ReSharper by copying our default hive.

Open a Visual Studio 2008 Command Prompt as an administrator. (Shift-right-click on Visual Studio 2008 Command Prompt, Run as… Administrator.)

cd C:\Program Files (x86)\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Tools\Bin
VsRegEx GetOrig 9.0 ReSharper

Be patient. This might take a minute or two. (If you want to delete the experimental hive later, run “VsRegEx Delete 9.0 ReSharper”. Note the space between 9.0 and ReSharper.)

Download and install your preferred daily build of ReSharper 4.5. IMPORTANT: When installing, make sure you disable all Visual Studio integration. We’ll be performing the integration manually in the next step.

Copying InstallExperimentalHive.Proj to the Bin directory of your ReSharper install location. (Mine is at C:\Program Files (x86)\JetBrains\ReSharper\v4.5\Bin).

cd C:\Program Files (x86)\JetBrains\ReSharper\v4.5\Bin
msbuild InstallExperimentalHive.Proj /t:Rebuild
devenv /RootSuffix ReSharper /Setup

Be patient. The last step might take a few minutes.

Create a shortcut to “devenv /RootSuffix ReSharper” on your desktop and mark the shortcut to run as an administrator. (Right-click the shortcut… Properties… Shortcut tab… Advanced… Run as administrator.) Double-click the shortcut and you should see:

ReSharper 4.5 in Experimental Hive

So there you have it. ReSharper 4.5 running in an experimental Visual Studio hive. If you install a new daily build of ReSharper 4.5, you won’t have to recreate the hive, but you may have to msbuild and devenv /Setup steps above. Have fun with trying out ReSharper 4.5!

Given the number of developers using Subversion, I’m surprised that no one on my blogroll has mentioned the new Subversion clients released in the last few weeks. Subversion, TortoiseSVN, and VisualSVN have all synchronized their version numbers on v1.5. I’ll talk about TortoiseSVN and Subversion changes. VisualSVN has some minor enhancements that basically expose the features introduced by Subversion 1.5. I’ll leave you to investigate them yourself.


Let’s talk TortoiseSVN… You can get the new client from here. N.B. If you’re running 64-bit Windows (XP, Vista, or Server 2003/2008), make sure you grab the 64-bit installer. Shell extensions run directly inside Windows Explorer, which on 64-bit Windows is a 64-bit process. So you don’t get any WoW (Windows-on-Windows) goodness that allows 32-bit executables to run on 64-bit Windows.

New Overlays

The most noticeable change is the new overlay icons.


Unversioned and ignored files now have their own overlays, which I find especially useful.  The problem in the past was that Windows only has 12 overlay slots available.  These slots could be easily exhausted if you had multiple shell extensions installed, such as TortoiseSVN and TortoiseCVS.  Tortoise clients now have a common overlay handler, which somewhat mitigates this problem.


Delete Unversioned Files

Over time, working copies tend to get crufty – at least mine do. I end up having extra unversioned files and directories – from tools, builds, half-implemented refactorings that you think better of – littering your working copy. Every once in awhile, I would just grab a clean working copy and delete the old. I then went to the trouble of creating PowerShell script to clean up my working copy. Now TortoiseSVN 1.5 includes this feature. Simply SHIFT-right click in your working copy and select “Delete unversioned items” from the context menu.  N.B. This option only appears if you hold down SHIFT.


Other Improvements

The repository browser has also been completely reworked.  It now shows a two pane view similar to Windows Explorer.


The revision graph has also been rewritten and is much easier to use.


Client-side caching has been improved, making TortoiseSVN more responsive. Merging has improved. Changelists have been added. Lots of new features. You can read the release notes for more information.


Subversion has made a lot improvements, which can be found in the release notes. If you’re just running TortoiseSVN, you don’t need to install the Subversion binaries. TortoiseSVN includes the SVN libraries. You only need the Subversion client and/or server if:

  1. You want to use Subversion from the command line via svn.exe and/or svnadmin.exe either directly or in scripts.
  2. You are running a server using svnserve (svn://) or Apache (http:// or https://).

You can download the Windows client and/or server from a few different places, each with advantages and disadvantages:

  • CollabNet – On the positive side, the MSI installer is quick to get you up and running. It adds svn.exe to your path and, if you install the server, you can select between svnserve.exe (svn://) and Apache (http:// or https://) easily. On the downside, you have to register on the CollabNet site and the downloaded binaries do not include support for Berkley DB, only FSFS. FSFS is the default for new repositories, but if you’ve got some older repositories around, they’re probably BDB. The CollabNet binaries complain bitterly about BDB repositories: “svnadmin: Failed to load module for FS type ‘bdb’”. Honestly I would recommend staying away from this package.
  • Tigris – Scroll down to and grab that. It includes both FSFS and BDB support, but you’re on your own configuring svnserve.exe. It’s not that hard and I document the steps here. This package is great if you just want to run svnserve.exe to access your repositories via svn://. If you want to run Apache to enable access your repositories over http:// and https://, you’re on your own to download and configure Apache. If you want to do that, then I recommend…
  • VisualSVN Server – Although VisualSVN (the Visual Studio add-in) is a commercial product, VisualSVN Server is completely free. This is the easiest way to get a Subversion server up and running with Apache. You can go from a clean Windows box to a working Subversion server in under 10 minutes. As an added bonus, it includes a MMC management console.

Upgrading the Repository Format (optional)

Although Subversion 1.5 can work with older repository formats, some of the new features, such as merge tracking, require you to upgrade your repository to the latest format. (See “Compatbility Concerns” in the release notes for full information regarding required client, server, and repository versions for various features.) Subversion will not upgrade your repository automatically. If you want to use the new features requiring a repository upgrade, you must run the following command:

svnadmin upgrade <PATH_TO_REPO>

where <PATH_TO_REPO> is the physical path and not a URL.

If you need to upgrade a lot of repositories and you’ve got PowerShell installed, you can do the following (assuming your repository root is c:\SrcRepos):

cd \SrcRepos
dir -name | foreach { svnadmin upgrade $_ }

Cyrus SASL and NTLM

TortoiseSVN and svnserve now include Cyrus SASL (Simple Authentication and Security Layer) support, which allows you to use a variety of authentication/encryption mechanisms, most importantly for Windows users – NTLM and Kerberos. Subversion clients and servers prior to 1.5 only support ANONYMOUS and CRAM-MD5. You’ll need to be running v1.5 on both sides of the wire to use the other protocols. The ZIP package from Tigris includes NTLM, but not Kerberos. If you want to use Kerberos, you’ll have to download saslGSSAPI.dll and add it to your sasl-plugins directory.

WARNING: I spent the better part of an afternoon trying to get svnserve.exe authenticating against the local Security Account Metabase (SAM) without success. (i.e. Using local Windows accounts to authenticate Subversion users.) The documentation is sparse to non-existent. I was able to get SASL to read its configuration and load the NTLM plug-in, but I could never successfully authenticate. Even with the correct username/password, it just prompted me again. It could be a problem with SASL defaulting to NTLMv1, which Vista disables by default for security reasons. If I figure out how to make this work, I’ll post a solution…


A build automation tool… now with less XML…

psake is a build automation tool written in PowerShell. It avoids the angle-bracket tax associated with executable XML by leveraging the PowerShell syntax in your build scripts. psake has a syntax inspired by rake (aka make in Ruby) and bake (aka make in Boo), but is easier to script because it leverages your existent command-line knowledge.

psake is pronounced sake – as in Japanese rice wine. It does NOT rhyme with make, bake, or rake.

psake is a proof-of-concept still in the early stages of development. It consists of a single file, psake.ps1, which contains all the logic for creating a graph of dependent tasks and executing them in the correct order. You can download it from Google Code using Subversion or TortoiseSVN:

svn checkout psake-read-only

Here is a simple psake build script:

properties {
  $testMessage = ‘Executed Test!’
  $compileMessage = ‘Executed Compile!’
  $cleanMessage = ‘Executed Clean!’

task default -depends Test

task Test -depends Compile, Clean {
  Write-Host $testMessage

task Compile -depends Clean {
  Write-Host $compileMessage

task Clean {
  Write-Host $cleanMessage

The properties and task script blocks can contain any valid PowerShell commands. To execute the script, simply type:

psake [task(s)]

(This assumes that psake.ps1 is in your PowerShell path.) If you don't specify a task or list of tasks (separated by spaces), it will look for a task named "default". You can display the command line syntax by typing:

psake -help

psake [buildFile] [tasks] [-framework ver] [-debug]
  where buildFile is the name of the build file, (default: default.ps1)
        tasks is a list of tasks to execute from the build file,
        ver is the .NET Framework version to target - 1.0, 1.1, 2.0, 3.0, or 3.5
            3.5 is the default
        debug dumps information the tasks.
psake -help
  Displays this message.

Remember that psake is syntactic sugar around PowerShell. So anything you can do in PowerShell, you can do in psake. That means that you can run MSBuild, NAnt, or other scripts. There is no need to completely replace your current build system. You can use psake to automate and extend it!

psake automatically adds the appropriate version of .NET Framework to its path. So you can access MSBuild, csc.exe, vbc.exe, or any other tools installed in $env:windir\Microsoft.NET\Framework\$version\ without the fully qualified path.

task default -depends DisplayNotice
task DisplayNotice {
  msbuild /version

As I mentioned earlier, psake is a proof-of-concept. You're likely to find some rough edges. I am releasing to the community under a MIT License. I would love to get your feedback and ideas for improving it. If you are interested in contributing, please contact me. Go forth and free yourselves from the shackles of executable XML! Take a sip of psake and enjoy!

I’m writing some integration tests around the .NET PetShop, which has no tests whatsoever. Since the architecture is tightly coupled, you can’t really start writing unit tests effectively. You have to start applying Michael Feather’s techniques for breaking dependencies. Before doing that, I want some smoke tests around the application. That’s where WatiN comes in. I am writing integration tests at the browser level. These tests are slow because you’re exercising the full stack – browser to web server to database. You need at least some of these full stack tests in every application. A good heuristic (for a large application) is a few dozen full stack integration tests, a few hundred presenter/controller integration tests, and a few thousand unit tests. (Smaller applications would probably be a dozen full stack integration, 50 presenter/controller integration, and a few hundred unit tests.) Enough testing theory… I wrote the following unit test:


public void CanLoadHomePage() {

    using(var ie = new IE(“http://localhost:9999″)) {

        Assert.AreEqual(“Welcome to .NET Pet Shop Evolved”, ie.Title);




When I ran the test (using Gallio‘s awesome ReSharper 4 Unit Test Runner support for MbUnit), Internet Explorer appeared, but I got a failed unit test:


and this stack trace (reproduced in text form from the image for Google’s indexing benefit):

WatiN.Core.Exceptions.TimeoutException: Timeout while waiting for main document becoming available
   at WatiN.Core.WaitForComplete.ThrowExceptionWhenTimeout(String timeoutMessage)
   at WatiN.Core.WaitForComplete.WaitWhileMainDocumentNotAvailable(DomContainer domContainer)
   at WatiN.Core.WaitForComplete.WaitForCompleteOrTimeout()
   at WatiN.Core.IEWaitForComplete.DoWait()
   at WatiN.Core.DomContainer.WaitForComplete(IWait waitForComplete)
   at WatiN.Core.IE.WaitForComplete()
   at WatiN.Core.IE.CreateNewIEAndGoToUri(Uri uri, LogonDialogHandler logonDialogHandler, Boolean createInNewProcess)
   at WatiN.Core.IE..ctor(String url)
   at WatiNTests.HomePageTests.CanLoadHomePage


Alrighty then. A TimeoutException and the Internet Explorer* instance was left stranded on my desktop. Taking a look at WatiN’s FAQ, I find this:

Which windows versions are supported?

Windows 2000, Windows XP and Windows 2003. Using WatiN on Vista gives some problems when User Account Control (UAC) is enabled. If you disable UAC almost all WatiN unit tests pass.

Disable UAC to run a testing framework??? Note that I’ve used WatiN on Vista before without disabling UAC. So it had to be some other setting. I noticed that Internet Explorer was running in Protected Mode, which dramatically limits the damage that a hijacked browser can do. Protected Mode runs IE in low integrity mode. (Low integrity processes are dramatically limited in which window messages they can send to higher integrity processes – such as Visual Studio and where they can read/write files.)



The obvious solution is to turn off IE Protected Mode for the site. Easiest way to do this? Add the site to your trusted sites list.


Survey says!



So rather than turning off UAC or Protected Mode in IE completely, you can just add the site under test to your trusted sites list and WatiN works.

For the Paranoid

The astute among you may be wondering if I haven’t opened up a security vulnerability by adding http://localhost to my trusted sites list. Let’s put it this way… If some l33t haxor can drop files on your box and start a webserver, they have already pwned your box. They don’t need you to navigate to a local site with unprotected IE to infect you more. smile_tongue

* For the curious, I rarely use IE, mostly just for certain Microsoft sites that are still IE only. Heck, I’ve been running RCs of FireFox 3 for awhile and upgraded to the RTM version yesterday when it was released. If you haven’t tried FireFox 3, you really need to. Gmail is oodles faster in FF3 than IE or FF2. You might wonder why I’m using IE with WatiN… WatiN only started supporting FireFox as of WatiN v2, which is currently in CTP. Historically WatiN (and WatiR) have relied on IE’s COM automation API to interact with the browser, which is also why WatiN/R doesn’t provide a way of getting HTTP status codes – because the COM API doesn’t expose them!

For those of you who missed it, JetBrains officially released ReSharper 4 last week. A list of new features can be found here. Most notably is full support for C# 3.0 and LINQ, but there are improvements in lots of other areas. (I’ll point out these improvements in the Becoming a Jedi screencasts. I’ve got an episode planned all around the new C# 3.0 features, which should surface in the next few weeks.) New keymaps for both the Visual Studio and ReSharper 2.X/IDEA schemes can be found here. Congratulations to the entire JetBrains team for getting this release out the door! If you haven’t tried ReSharper 4, you owe it to yourself to take it for a spin.

My third episode of Becoming a Jedi is live. In this episode, I start looking at ReSharper’s refactoring capabilities.

Episode Listing

Part 1 of N: Code Browsing streaming download
Part 2 of N: Code Cleanup streaming download
Part 3 of N: Refactoring I streaming download

Streaming requires Silverlight 1.0 or higher. Download is via Microsoft Skydrive.

After finishing the episode, I realized that I committed a huge refactoring faux pas. I neglected to run unit tests after each refactoring. I was feeling cocky and just doing simple refactorings such as renames and similar. When I tried to run the application later, it failed because it could no longer find PetShop.SqlServerDAL.Category, which had been renamed to PetShop.Repositories.CategorySqlRepository. So even on simple refactorings, you need the safety net of a good suite of unit tests. Lesson learnt.