Month: September 2007

Close, but no iPod Touch for me

This weekend I actually got around to play with one in the Apple Store, and what can you say? The best music player yet designed.

However I will not make the upgrade yet for one reason, and one reason only.

My routine in the morning is short: Get up, get showered, get breakfast, out the door. If I take time to turn on my Macbook and download the podcasts from the night before and transfer them to the iPod, then it can add a significant 15 minutes to my routine.

I was expecting the Touch to be able to download my podcast subscriptions whilst I breakfasted, in order that I could listen to them as soon I left the house.

Then I could just listen to HanselMinutes (or other podcast) during my commute.

It can’t. The hardware/software is certainly capable, but the feature does not exist yet. The software is also locked down, so I can not add a RSS program for it. Maybe it will exist in future, but until it does I will stick with my broken Nano or buy a more open player like an iRiver. 

How to insert an assembly version number into a WiX script at build time

Things have been quiet on this blog regarding Team Foundation Server… this isn’t from lack of interest, merely that the server is doing a great job taking care of itself and thereby leaving me to get on with other pleasures… such as documentation of project process.

Well, there was one thing, but I was somewhat ashamed to show it. It seems like when anyone creates a cool Powershell script in 5 lines of code, there will be some RegEx ninja who will jump in and splice it into 1.5 lines.

Well, first the scenario. We are using AssemblyInfoTask in the build project. Each time a build is kicked off, this task will go check out an AssemblyInfo.cs file of your choosing, and increment the assembly version number inside it. If the build is ultimately successful, it will then check this file back into source control with the new version.

The problem was that I had a WiX project that built the MSI, and there was no automatic way to pick up this assembly value and put it in as a variable.

Well, there is a way to get it in there.. you run a Powershell script during the build process, and update the WiX file whilst it is being built.

1 : you need to get a MSBuild task that can invoke Powershell.. I used this one.

2 : Place the following Include in your MSbuild .Proj file

  <UsingTask TaskName=”PowerShell” AssemblyFile=”C:\Build\Tasks\PowershellMSBuildTask.dll” />

3: Define location of script file in project

  <PropertyGroup>
    ………..

    <ReplaceScript>C:\Build\Tasks\ReplaceVersion.ps1</ReplaceScript>
  </PropertyGroup>

4 : Add (or merge) the following target into your .Proj file. For completeness, I will include the full target definition:

  <Target Name=”AfterGet” Condition=”‘$(IsDesktopBuild)’!=’true'”>
    <CreateItem Include=”$(SolutionRoot)\Client\$(AssemblyInfoSpec)”>
      <Output ItemName=”AssemblyInfoFiles” TaskParameter=”Include” />
    </CreateItem>

    <Exec WorkingDirectory=”$(SolutionRoot)”
        Command=”$(TF) checkout /recursive $(AssemblyInfoSpec)”/>
   
    <PowerShell Script=”$(ReplaceScript)” />

  </Target>

5 : In your WiX files, wherever you want a version number, insert this string: x.x.x.x. Here is an example Environment.wxi

<?xml version=”1.0″ encoding=”utf-8″?><Include><?define UpgradeCode = “AAAA-AAAA-AAAA-AAAA-AAAAA” ?><?define CompanyName = “Best Cookie Company” ?><?define ProductName = “Cookie Client vx.x.x.x” ?>

<?define ProductVersion = “x.x.x.x” ?>

</Include>

6 : Add the following Powerscript file to the file system on your build machine. I called it ReplaceVersion.ps1, but you can name and place it where you want

#######################
# This function will extract assembly version from an AssemblyInfo.cs file
# and replace the value x.x.x.x in the destination file with this value
#######################
function replaceVersions([string]$assemblyFile, [string]$fileToFix)
{
 # Get the whole line where ‘AssemblyFileInfo exists 
 $version = (select-string -pattern “AssemblyFileVersion” $assemblyFile) -replace ‘\”‘,”;

 # Find the beginning of the version number
 $beginIndex = ($version.IndexOf(“(“) + 1);

 # Extract version number
 $version = $version.SubString($beginIndex, ($version.IndexOf(“)”) – $beginIndex));

 # Create a temp file to write to
 $tempFile = $fileToFix + “.temp”;

 # Copy target file to temp file
 get-content $fileToFix | set-content $tempFile;

 # Set target file to writable
 (Get-ChildItem $fileToFix).set_IsReadOnly( 0 );

 # Increment version
 $version = incrementVersion $version;

 # Replace x.x.x.x in temp file to version number. Copy it back to target.
 get-content $tempFile | % { $_.Replace(“x.x.x.x”, $version) } | set-content $fileToFix;

 # Output
 Write-Host $version + “written to WiX files”;
}

#######################
# This function will increment the version assembly string by one minor number
#######################

function incrementVersion([string]$version)
{
 # Increment version number
 $minorVersionStartIndex = $version.LastIndexOf(“.”);
 $majorVersion = $version.SubString(0, ($minorVersionStartIndex+1));
 $minorVersion = $version.SubString(($minorVersionStartIndex + 1), ($version.length – $minorVersionStartIndex -1));
 $minorVersionInt = [Int32]$minorVersion;
 $minorVersionInt++;
 $minorVersion = [String]$minorVersionInt;

 return $majorVersion + $minorVersion;
}

$wixInclude = “C:\Build\Build\WiX\Environment.wxi”;
$wixProject = “C:\Build\Build\WiX\Build.wixproj”;
$assemblyInfo = “C:\Build\Build\Client\AssemblyInfo.cs”;

replaceVersions $assemblyInfo $wixInclude;

replaceVersions $assemblyInfo $wixProject;

(Question: I thought to source control this.. but how much of a risk is that?? A developer could put any code they wanted inside it, and it would get called as part of the build process. That said, your build process should be running as a standard user anyhow)

I’m not really happy with this script, so if anyone wants to make it shorter, then feel free to let me know for the good of the community 🙂

_______________________________________________________

UPDATE: 27/09/2007

Already a couple of comments saying that this is a long hard way to do it… and you are right!

What I am looking for is:

  1. Build my assemblies with TFS build
  2. Update the minor version number of the assemblies
  3. Get this assembly number used as a variable inside WiX 3.0

It doesn’t have to be Powershell.. if there is a simple setting in WiX that will allow me to do this then let me know!

_______________________________________________________

UPDATE: 31/10/2007

Morten Lyhr has an alternative solution, which I’m happy to advertise as an alternative.

He describes my solution as ‘clumsy’, and I guess everyone is entitled to their opinion 🙂

http://morten.lyhr.dk/PermaLink,guid,26be3b8d-8c89-4b1a-8528-46426f256c04.aspx

However I strongly disagree: once you have my powershell script on the system then there is not a great deal of configuration to do inside of the .proj file. His solution requires A LOT of hacking the project file, which I’m sure will cause major headaches down the road.

Because of this, I suggest mine is in fact more ‘elegant’.

What would be better, if I ever get the time, is just create an MSBuild task to handle this all in one stepI’m thinking just to create a new MSBuild task that can do all this in one step…

Create Development Demos for Distribution

I think I was a bit optimistic. I thought my new Dual-Core 2GB super Dell laptop had enough power to drive a virtual machine full of databases and web services, as well as record the whole thing at the same time.

Well, I downloaded Camtasia Studio, because that is what DotNetRocks! TV uses… It is a great and easy to use tool.. it was just I hadn’t thought how best to optimize the process.

First cut: I started VMWare and started recording with Camtasia. Result: Didn’t work. VMWare was unresponsive trying this out.

Second cut: I connected to VMWare over Remote Desktop on the same machine… this worked much better. I cut off the Remote Desktop visual effects to help a bit.

Third cut: I installed Camtasia on my favorite MacBook, and connected to the VMware machine with Remote Desktop over my Wifi network, and recorded that way. The fastest yet!

In all, I created a 10 minute demo at 1280×800 in wmv format for no more than 12MB. This is the way to go!

Note: Yes, VMWare has a video facility, but it can not sync voice with it, and dubbing isn’t my thing. Anyhow, it seems fastest to do your processing on one machine and record on another in this way.

Leaving the collective: Web Services on other platforms

I’m preparing an internal presentation for my company about a cool tool we use that hooks up various web services in Visual Studio by drawing and connecting them on a canvas. Unfortunately there isn’t much point in my talking about it since you would have to pay $$$ and have one of our consultants on site to use it.

Nevertheless, I’m pretty excited about this and I thought: what is the best way to demonstrate a SOA system on a disconnected Virtual Machine? Well, by adding a few databases and web services that have nothing to do with Microsoft.

I’ve been listening to Scott Hansellmans podcast, and thought that RUBY would be a great one to try out, since it is apparently the next big thing.

In many ways it is. I got hold of something called InstantRails, and it provided me with a ‘one click’ Rails, MySQL database and Apache web server all good to go.

Writing web pages in Ruby is really easy. Writing Web Services.. well I spent a whole evening trying to work out what would take me a few clicks in Visual Studio, & didn’t succeed.

I then tried the Java J2EE route, and downloaded NetBeans with JBOSS, and here are my observations:

Versioning:

Java versioning is even more confusing than .NET, and that is saying something. At least when I say my web site is running ASP.NET 2.0, everyone can have a good level of confidence that we are talking the same version.

Speed:

Back in the day with my Pentium 3 and 128mb of RAM, Java was painfully slow to use as an IDE. I loved JBuilder (new version is built on Eclipse!), but it didn’t really compare to the Microsoft tools.

Well, today the playing field seems even. This isn’t really scientific, but Visual Studio 2005 takes about 100MB of my RAM, and NetBeans about 115MB. NetBeans seems to be a Java based IDE that is as performant as Visual Studio.

Features:

I’m not going to go here yet.. I only wanted to create some web services in J2EE, and I have to say that it is as easy as Visual Studio, and the integration with the bundled Tomcat and JBoss application servers are very good. I’d like to come back to this topic in a future post.