In our past jobs, Gordon and I worked as part of larger technical teams. As developers, we never had to worry about the installation routine. It’s a highly specialized area of software development. We had people to do that job for us.
Fortunately I’d had a little experience working with InstallShield but that mainly involved stepped through the wizard and trying not to adjust settings that I didn’t understand. (Which meant most of the settings.)
Working on Infovark, we’ve had to absorb a crash course on Windows Installer. Windows Installer is the official Microsoft sanctioned technology for deploying applications to Windows. If you want to get the compatibility logo on your product, you must use Windows Installer or a tool that generates Windows Installer compatible .MSI files.
Windows Installer has been around for a long time, going back to at least 1998. Version 1.0 shipped with Office 2000. In the time since, it’s gone through many changes and revisions. If you didn’t “grow up” with the technology over the years, it’s a daunting challenge to get up to speed.
We figured our best bet was to pick a software package to help us build our MSI files. But since we didn’t know Windows Installer very well, it was hard to evaluate which one to use.
The best place I found for information about Windows Installer and setup and deployment tools is InstallSite. Finding my way around was a bit tricky, but there’s lots of good information there.
I also found an awesome series of articles written by Robert Flaming about UAC and Windows Installer. There are a few stray articles not included in his table of contents: UAC in MSI.
The series describes the slow evolution of User Account Control and per-user settings from Windows 95 to the present. This helps put all the hacks and kludges in context.
This long history is what makes creating good software installation routines on Windows difficult, especially if you want to support multiple versions of the operating system. The differences between Windows XP and Windows Vista are particularly large.
So if you’re planning to deploy your software to the desktop, make sure to include a lot of time in your development budget for research, testing and troubleshooting. It’s harder than you think.
I’ve been a bystander in the Software Craftsmanship movement so far. I’m not sure why. I like the idea of software craftsmanship. I’m just not sure what it means in practice.
I’ve read the manifesto and considered signing it. I agree with the aims expressed there. I’ve also read the blogs of those skeptical or confused about the manifesto. I can’t decide what to do about it.
The best overview of the software craftsmanship idea is Mark Levinson’s Call to Arms article on InfoQ. It describes software craftsmanship as a response to the typical coding grind, where just-barely-good-enough software is shoveled out the door as rapidly as possible.
I understand and appreciate the feeling; I’ve been there. I know how much it hurts to release bad products that frustrate customers. But I’m not sure the software craftsmanship community has a solution to that problem yet. It’s early days, though, and over the past few months I’ve discovered some interesting ideas about software craftsmanship.
Recently I listened to a Hanselminutes podcast where Bob Martin discusses professionalism in programming. Uncle Bob made three points that caught my ear. He said that programming professionals:
On the subject of continuous learning, I recently watched Mary Poppendieck discuss deliberate practice in a webcast on InfoQ. The summary: To become an expert in any field, you need to seek out coaches that teach the skills you need and spend focused time practicing those skills. Continuous learning is about gathering resources, understanding the material, and gaining experience through repeated effort.
After listening to these two programming mavens, I remembered something I’d read a while back on Coding Horror about code kata. Dave Thomas, of pragmatic programming fame, coined the term code kata for exercises designed to improve programming skills. He has a list of code kata, but other code kata catalogs have appeared as well.
So maybe there’s hope for the software craftsmanship movement after all. We’ve moved from talking about abstract goals to ideas we can put into practice. There’s a slow consensus building as to what a professional looks like and how one becomes a professional. That’s encouraging.
Ultimately, software craftsmanship isn’t about signing a pledge. It’s about delivering quality product.
Though the Microsoft marketing drums have begun beating to the rhythm of Visual Studio 2010, most of us workaday code monkeys are still using Visual Studio 2008. And while VS 2008 is a great IDE for development — especially once you add ReSharper — it has a few configuration quirks that drive me up the wall.
Most of these quirks are hidden from the typical developer and only appear once you try to package and deploy your software. It’s the dreaded Works on My Machine syndrome.
And if there’s one Visual Studio build configuration setting that causes me to scream in anguish, it’s the CopyLocal property.
When you add a reference to another .dll in Visual Studio 2008, some default settings get applied.

The CopyLocal setting on the reference properties panel.
Here’s how the settings look after I added log4net to one of my projects. As you can see, the CopyLocal setting is set to True. Or is it?
If you move your solution to your build server, you might be surprised to find that CopyLocal isn’t actually copying the .dll. I was certainly surprised to find that my builds failing for inexplicable reasons.
It took me a while to figure out that Visual Studio 2008 is a dirty liar when it comes to CopyLocal. Let’s have a look at our .csproj file, shall we? You can load the XML in the .csproj file by following these directions.
Ah, there’s the contents of our csproj file. And there’s our reference to log4net, but…

Where's the CopyLocal setting?
The CopyLocal setting isn’t there! Within the log4net reference, we should see an XML element called Private. It should look like this:
But it’s clearly not there. Uh oh.
And because it’s not there, it might work on your machine but not on other machines. Even though the Visual Studio IDE represents CopyLocal as a Boolean value, it’s actually a ternary value. Where Booleans have two states, usually represented as True/False, Yes/No, or 1/0 pairs, ternary logic has three states:
Yikes! That’s a classic interface failure mode.
It turns out that the default for the CopyLocal setting is… something not quite True and not quite False. If you read the documentation for how to set the CopyLocal property, it mentions the weird logic Visual Studio uses to determine what the “default” should be. Argh.
To fix the problem, we reload our project in Visual Studio again. Then we toggle the CopyLocal setting from “not quite True, exactly” to “False” and then back to “totally, literally True”.
With apologies to the Violent Femmes, when I say CopyLocal, you best CopyLocal, motherf***er!!!
And now it’s really, truly TRUE. Honest. Take a look at our .csproj file now.

This is how CopyLocal=True ought to look.
And there it is, the CopyLocal setting. The way it should be. The way it should have been all along.
I don’t know whether Visual Studio 2010 fixes this problem. I haven’t looked at the VS 2010 Beta release to find out. I’m too busy manually editing all my .csproj files to get our Infovark builds working. But I really, really, really hope that the folks at Microsoft have done something to address the problem.
Here’s the simple interface design rule: If it isn’t a Boolean setting, it shouldn’t look like a Boolean setting.
Unless of course, you want to make the pages of The Daily WTF.
Every now and then I find a comment in my code that I’ve completely forgotten about.
When I run across one of these nuggets, I guess I have the same experience as someone who’s kept a journal for months or years. I read the note and think, was that me that wrote that? Did I know that I would come back here again? Was a sending a message to my future self?
// TODO: Improve the quality of these tests. DTHRASHER 6OCT2008
// We need to verify that the filter string is being generated properly.
// We need to add tests to verify sorting behavior.
// We need to separate the ActivityParameters unit tests from the MetaIndex integration tests.
// We need a staff of 10 developers to help us finish this product! ARGH.
These always give me a chuckle.
And then I think, what a jerk that DTHRASHER guy is! I can’t believe he left me all this work to do!
I skipped today’s DC Alt.NET meeting on JavaScript. With the other half of the Infovark tech team on vacation, I’m holding down the fort.
Fortunately, I was able to expand my programming knowledge by catching up on my blog reading, and particularly by watching Greg Young of IMIS give a presentation called Unshackle Your Domain at QCon in June.
If you’ve ever had to built a high-performance system or one that has strict auditing and reporting requirements, this presentation is for you. Greg’s company deals with financial systems, and you can tell he’s learned many best practices the hard way.
While I doubt we’ll need an architecture as robust as he describes for Infovark, I recognize many of the the problems and patterns he describes from my old jobs in software companies making records management software (auditing) and real estate systems (transactions and reporting).
The key insight is that for certain software solutions, it’s important to model state transitions as part of the problem domain.
But what I found most interesting was how his example system combined the principles of Domain-Driven Design with the older notion of Command-Query Separation.
I’d explain in more detail, but it’d probably be easier to just watch the presentation yourself.