Funny .NET Graphics

Is it the pedant in me? I just cannot stand these graphics. They seem inaccurate to me.

Ok, so REST builds on WPF, but the AJAX is just the latest version of ASP.NET AJAX which has been a separate download for over a year. LINQ doesn’t build on anything .NET 3.0 either!

Here is another picture which shows the same thing.

This just cannot be right. What parts of LINQ build on any of WPF, WCF, WF or CS? Which parts of ASP.NET build on those? None AFAIK. The same goes for the Add-in Framework.

It deceptive. But it is also a good example of how marketing slides are inaccurate.

Another Reason Why I Run Linux At Home

I admit it. I am cheap.

These numbers don’t mix with my poor mans mentality.

How about a nice free version of the Web Server edition or something?

Windows Server 2003 had a web version that was cheap. I don’t see an equivalent here.

What in the world are they thinking with the “without Hyper-V” versions? Talk about confusing.

Unfortunately the state of the Xen Hypervisor on my favorite Linux isn’t that great.

That is a few revs back. But I am pretty sure that OpenSUSE has great OOTB Xen support. So no “without Hyper-V” edition here.

MbUnit, NUnit, but not MSTest

Guess who can use MbUnit or NUnit but not MSTest.

Users of Visual Studio Team System 2008 Architecture Edition. That is who!

It is just another reason to scrap MSTest altogether. Just ignore its inferiority. Ignore its silly integration with Studio which can be had for free via NUnit in SharpDevelop. Ignore its confusing availability in various projects. Just use NUnit or MbUnit.

I could go on much further with the list of things you must ignore to sanely choose MSTest. Instead I will list only two more things. NUnit works great with Mono on Linux. NUnitForms is a sweet way to unit test forms.

Nant Complexity and the Boo Build System

When I first read the announcement about the Boo Build System (whose acronym I will refrain from using) I wasn’t sure it was necessary. Today I saw an announcement for the ability of Nantbuilder and realized I was very wrong.

Anyone who has used GNU Build tools will know how complex a build system can get. Why isn’t make just good enough? Why aren’t nant or msbuild good enough?

I really don’t believe that the boo build system solves the complexity of a large build system. That said I do believe that an equivalent build project in boobs would be far easier to read than its nant counterpart just due to the nature of boo vs. xml.

Lets take a look at a trivial project configuration in Nant vs. Boobs.

<?xml version=”1.0″?>
<project name=”Hello World” default=”build” basedir=”.”>
    <description>The Hello World of build files.</description>
    <property name=”debug” value=”true” overwrite=”false” />
    <target name=”clean” description=”remove all generated files”>
        <delete file=”HelloWorld.exe” failonerror=”false” />
        <delete file=”HelloWorld.pdb” failonerror=”false” />
    <target name=”build” description=”compiles the source code”>
        <csc target=”exe” output=”HelloWorld.exe” debug=”${debug}”>
                <includes name=”Hello.cs” />


import Boobs.Engine
import Boobs.Compiler.Extensions

Task(“build”) do (ctx):
        SourcesSet : [“hello.cs”],
        OutputFile : “HelloWorld.exe”,
        OutputTarget: TargetType.Exe

Task(“clean”) do:
    if Exist(“HelloWorld.exe”): Rm(“HelloWorld.exe”)
    if Exist(“HelloWorld.pdb”): Rm(“HelloWorld.pdb”)

Task(“default”, [“build”])

I know which one I’d rather maintain and I haven’t even used control flow logic. I have always though if statements in XML were goofy at best and stupid normally. In boobs, it IS boo. the if statement is boo’s if statement.

Need to iterate over numbered files? Use boo’s for statement or while statement. These things have always felt awkward in XML. This isn’t Nant that is falling short, it is XML.

If you have a nant configuration which is working for you, then by all means keep it up! But if you are just breaking into CI and thinking about Nant, you may want to consider the boo build system.

NUnitForms Requires Administrator Privilege

I am one of those crazy security paranoid former system administrator turned programmer. I am a windows user. I think I’m on the only one.

I do not run as Administrator. In Linux I use sudo or gksu or some variant. In Windows I get by with runas 99% of the time and the other 1% of the time I just “switch user”.

I’ve been struggling to use NUnitForms. Since I had been struggling I’d been leaving it and coming back to it. Today I made a break through and it had nothing to do with code or understanding how NUnitForms works. Unfortunately it had to do with my crazy security paranoia.

NUnitForms requires administrator privilege. Once I ran NUnit as administrator, the pesky tests started succeeding. But even this was a struggle.


Strangely, when I use the windows menu, search for “NUnit” and click the result, it works fine. When I perform the exact same action and right click and click “Run as administrator” from the context menu, I get a very strange result.


Fine. I can browse “c:\program files\NUnit 2.4.3\bin\” and right click launch NUnit.exe as administrator. Thankfully that works. But now comes my gripe!

All of my MRU information is different. In a program like NUnit this isn’t too big of a deal. It is more just annoying.

In Linux, using sudo, quite often it is possible to start a program as root, and yet have it still read its configuration from the normal place. sudo doesn’t change the HOME environment variable by default (this is like USERPROFILE and or HOMEPATH in windows). This means that if programs read their configuration information from a path relative to HOME, that you can start then with sudo and still get your local settings.

I am not sure if this is a good thing or a bad thing, but the flexibility of it is definitely welcome. If I want to set HOME, I can just start sudo with the -H option.

I miss you desktop Linux. Some days more than others, and especially today.

GNU Mailman and Apache mod_mbox

Over a year ago I saw mod_mbox. I love they way it provided nice looking archives and an Atom1 feed for a mailbox archived in the mbox2 format. I knew immediately that I wanted this for some Mailman lists which I provide.

Mailman does store its archives in mbox format. Unfortunately mod_mbox wants one mbox file per month, named a very specific way.

Here is how I got there. First, the tools:

  • Mhonarc is a mail to html converter used by popular sites such as and
  • Mharc is a web-based mail archiving system for multiple mailing lists.
  • Mharc has a tool called mbox-month-pack which does (almost)exactly what I want.
  • Mailman is already configured.
  • mod_mbox just needs to be plugged into a pre-configured apache.

The Procedure:

Mailman stores its archives in /var/lib/mailman/archives/private/ with complete mbox archives in one file in a file named ${list}.mbox/${list}.mbox. I just need to feed that to Mharc’s mbox-month-pack.

Massage the filenames a bit:

for i in ????-?? ; do mv $i ${i/-/}.mbox ; done

Setup Apache as the mod_mbox docs say.

Modify mailman’s list_members program to extract a encrypted password for each member, with output suitable for basic http authentication.

— /var/lib/mailman/bin/list_members   2007-06-12 08:49:33.000000000 -0400
+++ /var/lib/mailman/bin/list_members_pass      2007-11-08 23:04:20.000000000 -0500
@@ -80,6 +80,10 @@

from email.Utils import formataddr

+import crypt
+from random import randint
+import string
PROGRAM = sys.argv[0]
ENC = sys.getdefaultencoding()
@@ -140,6 +144,11 @@
         return status <> MemberAdaptor.ENABLED
     return status == WHYCHOICES[why]

+salt_chars = ‘./’ + string.ascii_letters + string.digits
+def crypt_password(password):
+    salt = salt_chars[randint(0, 63)] + salt_chars[randint(0, 63)]
+    return crypt.crypt(password, salt)

def main():
@@ -258,14 +267,16 @@
         for addr in rmembers:
             name = fullnames and mlist.getMemberName(addr) or ”
+            password = crypt_password(mlist.getMemberPassword(addr) or ”)
             # Filter out nomails
             if nomail and not whymatches(mlist, addr, why):
–            print >> fp, formataddr((safe(name), addr))
+            print >> fp, formataddr((safe(name), addr)) +”:”+password
     if digest:
         for addr in dmembers:
             name = fullnames and mlist.getMemberName(addr) or ”
+            password = crypt_password(mlist.getMemberPassword(addr) or ”)
             # Filter out nomails
             if nomail and not whymatches(mlist, addr, why):
@@ -278,7 +289,7 @@
                 # They’re getting MIME digests
                 if kind == ‘plain’:
–            print >> fp, formataddr((safe(name), addr))
+            print >> fp, formataddr((safe(name), addr)) +”:”+password


Wrap all of this up in a nice little script and insert into cron so that messages, usernames and passwords are refreshed hourly or daily.



for list in `$LISTLISTS -b` ; do
  if [[ ! -d $OUTDIR ]]; then mkdir $OUTDIR; fi
  if [[ ! -f $OUTDIR/.htaccess ]]; then
    cat >$OUTDIR/.htaccess <<EOD
AuthType Basic
AuthName “mailman Password Required”
AuthUserFile /var/passwords/$list.pwfile
Require valid-user

  $LISTMEMBERSPASS $list > /var/passwords/$list.pwfile

  pushd $OUTDIR
    for i in ????-?? ; do mv $i ${i/-/}.mbox ; done
    mod-mbox-util -v -c .



libapache2-mod-mbox is available on my Launchpad PPA.

mhonarc is available by default in debian.

mharc you will have to get the source and build.

  1. Say what you want about RSS vs Atom. I don’t care. Any tool that matters supports both… except mod_mbox.
  2. Yes, mbox isn’t the ideal mailbox format, but in this case it works

Gmail Was Upgraded. I Did Not Notice.

I didn’t realize that gmail’s web interface was upgraded recently. I am a user of the gmail macros Greasemonkey script. It stopped working right around the time my Gmail offered its new IMAP enable functionality.

IMAP is nice and all, but if I had to choose, I’d choose to have my Greasemonkey script work. Luckily the script has been updated to support the new gmail web interface.

You have to go manually install the script update. So if you were using it and it just stopped working, go upgrade!

It is worth it just for the “e” to archive functionality. “l” to label is just a bonus.

Tiling Windows Without Minimize All

Did you know you could do this in windows?

I didn’t, and I have wanted it for years – I only knew about “tile” in the taskbar itself – so I’d have to minimize all, restore the two I wanted and use that.

I’m VERY happy to have found this. I’m VERY angry that I’ve lived without knowing about it for this long. I hate my own ignorance.

Basically, I often work with only 1 display. I know Multi Monitor rules, but what about when you are on the road with your laptop only? So I want one window on the left and another one on the right.

From the above link:

  1. Click the taskbar entry for the first window you want to view;
  2. Press and hold down the “Ctrl” key;
  3. Click the taskbar entry for the second window you want to view – both of the taskbar entries should now be selected;
  4. Release the control key;
  5. Right-click on either of the taskbar entries you selected;
  6. Click “Tile Horizontally” if you want your windows to appear one above the other; or click “Tile Vertically” if you want your windows to appear side-by-side. If you are reading notes from the UCanWiki, it is often best to tile the window vertically.


Did I mention the part where I hate my own ignorance?

Test Driven Development – There is no excuse

There really is no excuse to not be using Test Driven Development. Any excuses are just that.

The Voidspace Techie Blogger has a great post about Spiking as an answer to one of the common excuses. My question: May I please have a job which involves only spiking all the time?  😉

I really do like doing new things and figuring them out and doing things I’ve never done before. If I have done it before then it isn’t interesting. I’m only half kidding about the spiking all the time job.

Still think your case is special? It isn’t. Still clinging to your excuses? TDD doesn’t work for you? Maybe you aren’t working for TDD! Yes it changes the way you work. That is the point! Its working BETTER!

Now if I could just figure out this NUnitForms I could test that much more.