Why Windows Sucks, or at least one reason…

My parents can’t get Microsoft Excel to work.

The symptoms was that after installing some other program, suddenly when they open a document they are greeted with a Microsoft Excel spreadsheet–but the entire content area is gray. No cells, no editing, no joy–just a large gray expance where the data should be. But the application is not frozen; oh, no. The whole thing seems to be behaving just fine, like a small puppy with a large candy stuck to its fur: the thing just hops around like all is well, despite the fact that there is this ugly red sticky mass hanging off its fur.

My usual recommendation in a situation like this: you’re hosed. Uninstall the entire application, uninstall the other offending application, and reinstall from scratch–and hopefully this will clear the whole mess up.

So my father tried this–no joy. Of course the results were different: he can create a new spreadsheet just fine. But try to open an existing spreadsheet–gray empty blob. The red sticky candy has somewhat been removed–but there is still a read sticky matted spot where there should be clean brown fur.

*sigh*

I hate Windows. And one of the reasons why is this sort of odd-ball DLL hell that Windows seems to infect all applications. Without ever having seen the source code to Microsoft Excel or this other application, I can tell you exactly what failed: there is some DLL somewhere, which was “upgraded” by the other application, which broke Excel. (The other application also provided spreadsheet-like functionality in one of its Windows, which makes me think they shipped with some DLLs used by Excel.)

And here’s the problem. In a large corporate environment we build our applications with tons of plug-ins: DLLs, Jar files, MacOS X Frameworks–and we do this because we want to either leverage code written by someone else without increasing the overall shipping footprint of our application, or because we want to minimize inter-team communications, which is the bane of any large software development team. (Because as we all know, team communications is essentially an O(N**2) problem–unless we can create multiple groups, in which case we can reduce this to a max(O(G**2),O(T**2)) problem with G*T = N, where G is the number of groups you’ve broken your overall team down into.)

We go along, we test our software, we see everything works, we ship. Job done.

Except… Well, except that, because three quarters of the code we just shipped is someone else’s, and because that code (in the form of frameworks, Jars, DLLs, whatever) can be replaced willy-nilly, with at best only a lose contract as to how those DLLs work, a lose contract that we may not have used correctly because some guy wanted to go home early rather than make his code more bullet proof, or because he didn’t understand the contract but by coincidence his code worked anyways… Well, you see where I’m going with this.

Someone ships an update to some plugin, which ships a new version of some DLL, and your code breaks in some subtle, bit-rottish sort of way. Something flickers before its drawn, or under some situations a file opened before some application ran causes a crash–the code you thought was bullet proof wasn’t all that bullet proof after all.

Windows seems especially prone to this problem: I don’t know of a single application that ships as a single, self-contained application. Every one of them breaks down into a million little DLLs, even if they are all Microsoft DLLs–and none of them are under your control. And worse: we’re encouraged to slam all of our DLLs in a common area (\Windows\System or wherever), which causes the potential for bitrot to increase.

Your application isn’t rotting from the inside; it just seems like it.

A few years go by, the user has made compromise after compromise in their workflow–after having learned the hard way because of some weird DLL interaction on his system that he is supposed to shake the mouse like a voodoo stick before he is allowed to open his Word document–and something finally gives. The pile of crap dumped into \Windows\System finally gives away, and the whole thing just dies a horrible, flaming death.

And the user, thinking that somehow it is his hardware that has failed (and not a pile of subtly incompatible software which caused his system to die), decides that, well, what the hell; perhaps it is time to replace my computer. After all, the computer is, as far as the user is concerned, behaving exactly like his car: after a few thousand miles, a filter needs to be replaced; a few thousand more, a gas shock needs fixing; a few thousand more, a gasket blows, and he is stranded by the side of the road.

We’re used to the idea that things rot, so we assume that our computers are also failing because of rot. But it isn’t rot–it’s a slow accumulation of slightly incompatible software causing things to die.

When I was at Microsoft for a few weeks I discovered that many people there simply reach out to a global server where all of Microsoft’s product lives, and they just blow away the entire contents of their computers and reinstall what they need from scratch.

End-users cannot do this.

And I think that’s why I hate Windows: because this bug, this defect, this software error, which could be solved by preventing third party applications from installing DLLs in a shared directory, causes the computer to behave exactly like an old creaky car–which encourages users to replace their computers every few years rather than just reformatting the hard disks of their existing (and perfectly good) computers.

It’s a software design defect which makes Microsoft money.

Forbes on Windows Vista

Dim Vista

Windows Vista: more than five years in the making, more than 50 million lines of code. The result? A vista slightly more inspiring than the one over the town dump. The new slogan is: “The ‘Wow’ Starts Now,” and Microsoft touts new features, many filched shamelessly from Apple’s Macintosh. But as with every previous version, there’s no wow here, not even in ironic quotes. Vista is at best mildly annoying and at worst makes you want to rush to Redmond, Wash. and rip somebody’s liver out.

Vista is a fading theme park with a few new rides, lots of patched-up old ones and bored kids in desperate need of adult supervision running things. If I can find plenty of problems in a matter of hours, why can’t Microsoft? Most likely answer: It did–and it doesn’t care.

Example: If malware somehow gets into your machine, Windows Firewall will not stop it from making outbound Internet connections to do its evil deeds. If you turn off that firewall in favor of a better one, the Windows Firewall control panel will admonish: “Your computer is not protected; turn on Windows Firewall.” But the Windows Security Center will correctly tell you that a firewall is on and that you shouldn’t run two at a time. Call it convistancy.

Gaffes like this make you wonder if security really is improved as much as Microsoft claims. You’ll still have to add your own antivirus software, a new Vista-ready version at that. And Vista’s irritating and repeated warnings about possible security breaches don’t always mean what they say and are usually irrelevant. You’ll take them as seriously as the boy who cried wolf, making them useless as defensive tools.

Ouch.

I Hate Windows, Pt. 1 (An On-Going Series)

Perhaps this is true for all platforms, but it seems especially true for Microsoft Windows development: because of the number of tricks, code oddities and places where the way things work is completely unclear, it seems that Windows programming experience is measured not so much by length of time, but by the number of battle scars you accumulate fighting some odd little API call or another. You know the feeling: you read MSDN, you make the call you think should work, you’ve got all of the resources in the right place–yet, instead of success you get a null handle or some obscure error code you’ve never heard of.

So off you go to Google, type in the error code–and find about fifty messages in about fifty different sites all saying the same thing: “WTF?” Occassionally suggestions are made–which are about as worthwhile as shaking voodoo sticks and sacrificing chickens to Odin and Thor. Then, finally, you either try shaking your own voodoo sticks or you come across one brief flicker of light amongst the darkness of ignorance–and you discover finally what when wrong. Sometimes it’s an unclear API, or sometimes it’s some odd exception to an existing API that, had you actually had the time to read the entire MSDN article on the subject rather than just skim it looking for the information you need, you would have known about.

Feeling silly and wondering why you didn’t take your mother’s advice to become an Architect, you move on. And another scar hardens on your brain.

I Hate Windows.

As I encounter them, I’ll try to post them here. And I have one that I recently encountered at work with WinCE, though it appears to also apply to the desktop version of Windows.

Where did my help go?

If you press ‘F1’ on your keyboard on Windows, you should get context-sensitive help for your application.

This little bit of magic works by the Windows OS sending your current WinProc an WM_HELP message, which you can then respond to by opening up the on-line help manual to the page which describes the dialog box or window you’re currently working in.

All well and good.

Well, I was converting a bunch of dialog boxes into a tabbed dialog box by using the PropertySheet() call in Microsoft Windows, which worked fairly well.

Except help stopped working.

Scratching my head I discovered that when you live as a property sheet, the callback for your pane looks very much like a DialogProc that you’d pass to DialogBox or some other call like that. Except all of a sudden many messages that have a perfectly valid WM_XXX counterpart–such as WM_HELP–get turned into WM_NOTIFY messages instead.

So, gratuetously, instead of sending you WM_HELP when someone asks for help, you instead get a WM_NOTIFY message with notification code PSN_HELP.

As I was adding the following switch statement to my code:

    case WM_NOTIFY:
    {
        NMHDR *ppsn = (NMHDR *)lParam;
        if (ppsn->code == PSN_HELP) {
            ::SendMessage(hWnd,WM_HELP,0,0);
        } // other notification handlers go here...
    }

I had to wonder–why didn’t Microsoft do this for me? Something perverse? Historic reasons? I dunno, and I suspect resending the message as a WM_HELP message rather than just processing it there at the SendMessage call would be better.

But I wasted a good hour on this one.