Thursday, March 19, 2009

Topshelf

At work, I'm currently working on a project which requires the integration of several different systems, some of them hosted on the internet, and some on different sides of the corporate firewalls. This means that we can expect to lose connections between systems, which naturally pointed us in the direction of message queues, which are designed for such scenarios. A chat with a former colleague pointed me in the direction of enterprise service buses as the core technology to take care of all the plumbing; and after comparing feature sets with our requirements, I downloaded MassTransit.

What interested me was a spin-off from the MassTransit project, called Topshelf, which has a single and simple aim - to get rid of all the cruft associated with actually launching .NET programs, especially all the boilerplate code you have to come up with to run services.

I ran into a few issues though: the first was that before, I had been using the WiX's ServiceInstall code to handle all the service registration, such as setting the service name, description and credentials. However, Topshelf provides its own code to do that, and the two aren't compatible. In the end, the solution I came up with was to remove the WiX code and use Topshelf's, which would be invoked by a custom action in the WiX script:

<CustomAction Id="InstallService" FileKey="ServiceExe" ExeCommand="/install" />
<InstallExecuteSequence>
    <Custom Action="InstallService" After="InstallFinalize" />
</InstallExecuteSequence>

FileKey is just a reference to the Id of the executable for the service, and ExeCommand contains the parameter(s) to pass to it.

All well and good, but unfortunately, Topshelf's implementation currently launches the same dialog box that installutil does, and if you're trying to produce an unattended install file, a dialog box is the last thing you want. I've had a little play around with the source code and came up with something which would technically work, but was nowhere near as elegant as the rest of the code, so I'm not planning on submitting it.

I did add a few refactorings and documentation into the codebase, nothing clever or anything; I then submitted the changes as a patch to Dru, and within the hour, they had been committed to trunk. This really reminds me why I love open-source programming so much - if the application doesn't do quite what you want it to do, you can download the source code and modify it, and if it works well, you can contribute that change back to the community. Talk about a win-win situation. Non-open source companies have to think about every way that people will use their software, and then program all that functionality in, thus proving the 80-20 rule - 80% of your users are only using 20% of your application's functionality. Did you know that Microsoft Word has a Japanese Greeting dialog box, which allows you to select a greeting specific to the month of the year?! I wonder even how many Japanese people know it exists?

Japanese Greeting dialog box from Microsoft Word 2003

Speaking of contributing to open source, I've accepted a couple of patches to my SvnRevisionLabeller project, and should be releasing a new build soon, once I've figured how to get some good tests in there. You are testing your software, right?!

No comments: