Wednesday 9 September 2009

Cruise control with MSBuild - Switching a reference on the build server

Background

This article is the result of the following problem I encountered a few days ago: We have a piece of software which references a third party dll. We had to deploy the software to a customer with a 64bit server.

This isn’t a problem for the code written in house, as it is all managed so runs in a 64bit environment no problem. Unfortunately, the third party dll we are using is 32 bit specific. There is a 64 bit version, but in order to develop against the library we have to reference the 32 bit dll (we all work on 32 bit machines).

The build setup

First off, we keep all third party dlls within a folder in our solution, so anyone can grab the source code from VSS (I know...) and compile it.

We run Continuous Integration using Cruise Control and MSBuild to do the building by reading our solutions files. On every check-in, a build is triggered, resulting in a build containing everything the software needs, ready to deploy.

Fixing the problem

First we deployed the software to a 64 bit server and tried simply copying over the 32 bit dll with the 64 bit version – they are both the same version number, so with fingers crossed we fired up the app. No such luck:

The located assembly's manifest definition does not match the assembly reference

Kind of expected that to be honest...

We then restructured our external references folder ‘BinRefs’ a little, and added the 64 bit dlls to the solution:

Then changed the reference in the project file to point to the new location for the 32 bit dll.

The plan was to get the build server to open the project file containing the reference to the 32 bit dll and change the path to the dll so it points at the 64 bit version before building the solution.

VS2008 project files hold their references to dlls as below:

So I simply needed to replace the string

“..\..\BinRefs\32Bit\SomeLibrary.dll”

With the relative path to the 64 bit dll

“..\..\BinRefs\64Bit\SomeLibrary.dll”

Before MSBuild starts compiling.

A quick and dirty VBScript with a batch file to kick it off takes care of the job of replacing the HintPath in the project file:

VBScript (Replace32bitDLL.vbs)

dim fso
dim txtStr
dim strHolder
dim strFileToFix

' Replace reference to SomLibrary in MyProject project
strFileToFix = "Build64\Services\PDF\MyProject.vbproj"
set fso = wscript.createobject("scripting.filesystemobject")
set txtStr = fso.opentextfile(strFileToFix,1,false,0)
strHolder = txtstr.readall
txtStr.close
set txtStr = nothing
strHolder = replace(strHolder,"..\..\BinRefs\32Bit\SomeLibrary.dll","..\..\BinRefs\64Bit\SomeLibrary.dll",1,-1,vbtextcompare)

set txtStr = fso.createtextfile(strFileToFix,true,false)
txtStr.write(strHolder)
txtStr.close
set txtStr = nothing


Batch Script (Replace32bitDLL.cmd)

ECHO StartingDllReplace
CScript Replace32bitDll.vbs
ECHO FinishedDllReplace


Finally a task is added to the project section in the Cruise Control config file before the call to MSBuild (shown in bold):


<tasks>
<exec>
<baseDirectory>E:\Dev\Development</baseDirectory>
<executable>Replace32bitDLL.cmd</executable>
</exec>

<msbuild>
&msb3Exe;
<workingDirectory>E:\Development\Build64</workingDirectory>
<projectFile>MySolution.sln</projectFile>
&releaseBuildArgs;
<targets>Build</targets>
&msBuildLogger;
</msbuild>
</tasks>


And you’re sorted. Check-ins result in builds ready to be deployed to 64 bit machines.

Announcing TellyFeed - Beta Release

TellyFeed - Never miss another film when it's on TV!

What it’s all about?

TellyFeed was a little idea that came from a FaceBook app I built a couple of years ago to learn about the FaceBook api.

The idea came about as a way to find out when films were gonna be on tv (which is pretty much all I personally use it for) and it seems to do a relatively good job.

Basically, you enter a list of film or TV programme titles and TellyFeed can let you know if they’re gonna be on TV over the next 5 or so days. Fairly handy if you’ve got a fancy TV recording Freeview box and want to build up a little film collection.

Just hook up your RSS reader and you’ll never miss that film you’ve been meaning to watch.

So why did I build it?

I just finished reading Evans’ Domain Driven Design and decided that if I wanted it to sink in, I should probably try it all out.

I built the application basically as a controlled experiment... It’s a fairly simple application with a few business rules and concerns. I knew exactly what I wanted it to do, so I could sort of play the role of developer and domain expert.

I learnt a lot (Dependency Injection, the Repository Pattern, A fair bit more knowledge of the MVC framework, a good old bit about domain modelling, a bit about nHibernate, SubSonic SimpleRepository and quite probably a lot more.) which is good.

I'll be adding some blog posts over the coming weeks outlining some of the things I learned, and how I went about achieving some of the functionality on the site, so stay tuned!

Enjoy the site I hope you find it useful.