Why does Add or Remove Programs show a large blank space?


Some people have noticed that certain programs cause the Add or Remove Programs control panel to create an enormous amount of blank space. What's going on?

These are programs that have bad custom uninstall icon registrations.

If you go to the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall, you'll find a list of programs that have registered for appearing in the Add or Remove Programs control panel. Some of them might have been so kind as to provide a "DisplayIcon" value, thereby saving the control panel the indignity of having to guess at an appropriate icon.

Unfortunately, if they put a bad icon registration in that registry value, the result is a bunch of blank space since the control panel is trying to reserve space for a bogus icon.

The format of the icon registration is a filename, optionally followed by a comma and a decimal number.

C:\full\path\to\icon\file.dll
C:\full\path\to\icon\file.dll,123

Since this is not a command line, quotation marks are not necessary (although they are tolerated). Furthermore, the number can be any value except for -1. Why is -1 forbidden? Because the ExtractIcon function treats the value -1 specially.

If the icon file does not exist in the icon file, or if the icon number is -1, then the icon specification is invalid and the Add or Remove Programs control panel will reserve an odd amount of space for an icon that doesn't exist.

Perhaps the Add or Remove Programs control panel should be more tolerant of invalid icon registrations? Or should it stay the way it is, adhering to the "Don't bend over backwards to fix buggy programs; force the program authors to fix their own bugs" policy that so many of my readers advocate? (Noting furthermore that refusing to accomodate invalid icon registrations makes it look like Add or Remove Programs is the buggy one.)

Comments (43)
  1. barrkel says:

    I think that the mantra "be strict in what you provide, be lenient in what you expect" is always the best policy to adopt when integrating with other parts of a heterogenous environment.

  2. Dave says:

    In general I like that philosophy in situations where tolerance of ill-formed input benefits the user. However, if you quietly tolerate bad A/R entries then you end up with the junk we have today. I’d prefer to have it show an ugly broken-image icon to reinforce to the app maker that they made a mistake.

    The "lenient" approach is what has made web pages such a mess today; the trend was started by Netscape and carried on to IE. You can write the most ugly, unmatched, illegal garbage and it will often render without any indication that it’s garbage. Wouldn’t it be better to have the browser display some sort of subtle indication that the author/designer didn’t do their job?

  3. Jack Mathews says:

    Yeah, except this is obviously a case of an uninitialized variable, or a variable initialized to a stupid default value (like short(-1)).

    I’d normally agree with you that buggy programs shouldn’t be tolerated, but that doesn’t mean you can write code like:

    short iconHeight = -1;

    if ( IsValidIcon() )

    {

    iconHeight = GetIconHeight();

    }

    SetControlIconHeight( iconHeight );

  4. Anonymous says:

    Without question, if you are the provider of a "round hole" (integration point) it is your responsibility to ensure a "square peg" (screwy vendor) will NOT fit or break adjoining pegs who correctly fit!

    You provide the platform, the foundation should be firm.

    Also, you’re frick’n MSFT … you have the budget to provide the foundation.

    Inexcusable.

  5. jwf says:

    I can deal with the space.

    What I can’t figure out is why the add/remove dialog is so lame as to completely ignore page up, page down, home, and end keys.

    And snapping to a letter would be great also (e.g. I hit "f" and it scrolls to the first program with f in the title).

    Both of which have been an issue since 1999 betas.

  6. Almost Anonymous says:

    "I think that the mantra "be strict in what you provide, be lenient in what you expect" is always the best policy to adopt when integrating with other parts of a heterogenous environment."

    This is a horrible mantra and the source of this problem and countless others.

    What should happen if the display icon is not set properly? The entire program item should not be displayed at all. That may seem like it would make things worse, but it really wouldn’t. The developer would see immediately that he/she screwed something up and fix it.

    Unfortunately, it’s too late to change this now — once you’ve made something half-work you cannot change it. However, for new development, Windows should be STRICT in what it accepts and there would be much less problems of the type that Raymond describes over and over.

  7. sporkmaster says:

    Maybe I’m cynical, but my feel is that lots of the arcana and undocumented bits of the win32 API have roots in win3.1 coding. Get thee down to the Software Clearance Center and pick up a copy of the 3.1 SDK docs….

  8. SporkMaster says:

    One other comment– A/RP seems unfinished in my opinion. And, now it is frozen in a block of amber. I can’t help but think that this bogus icon behavior is something that a developer doing realistic unit testing would have picked up on and fixed. (Not to say that I haven’t made such mistakes in my own code before, but I say with a straight face that sanity testing an icon index would have been in my unit test…)

  9. Daev says:

    I guess lots of people think that worsening the daily computer-using experience of millions is the correct way for Microsoft to communicate with software developers — to "encourage" or "force" some company that’s probably long since moved on to go back and magically deliver patches to everyone using their product.

    A liberal, accomodating system cushions the impact of the rough world of existing software on the OS’s actual customers: the users. A strict system subordinates comfortable OS/user interaction to the quixotic goal of setting up some kind of long-distance reward-and-punishment loop between the OS designers and a small group of sloppy application developers.

    The fallback solution of leaving some extra blank space in Add/Remove programs sounds fine. Any complicated system is inherently quirky, arcane and "illogical." These things aren’t bad. They’re decent approaches for insoluble edge cases.

  10. Fábio says:

    Instead of showing a blank space or the invalid icon it should display a default icon. It’d force the program authors to work the problems if they want to show their own icon.

  11. Thierry says:

    I am also wondering why a default icon isn’t selected instead of using a blank space.

  12. "I am also wondering why a default icon isn’t selected instead of using a blank space."

    It’s not like there was a conscious decision "Hey, let’s show a big blank space". It’s just fall-out from the way the code is written. Watch:

    HICON hico = ExtractIcon(pszDefaultIconLocation, iDefaultIcon);

    if (hico) {

    ICONINFO ii;

    GetIconInfo(hico, &ii);

    BITMAP bm;

    GetObject(ii.hbmColor, sizeof(bm), &bm);

    height = bm.bmHeight;

    // cleanup deleted for expository purposes

    } else {

    height = 0;

    }

    Read this and understand it and you will see where the big blank space comes from.

  13. Xavier says:

    The old programmer’s adage "be as lenient as possible in what you accept, and as strict as possible in what you output" should probably be applied.

    In this case, if the Add/Remove panel code can’t figure out how to get a valid icon out of the DisplayIcon value, then it really should display anything–including odd amounts of empty space–for the icon at all.

  14. Xavier says:

    That should read "…shouldn’t display anything…" where it says "…should display anything…"

  15. binaryc says:

    I’m still not too sure where it comes from. If the icon filename is wrong it should fall in to the else case and set height to 0 right?

  16. Thierry says:

    "It’s not like there was a conscious decision "Hey, let’s show a big blank space". It’s just fall-out from the way the code is written."

    Fair enough. Certainly this is something that can be fixed in a service pack or hotfix? Was it? Or is it still there?

  17. Thierry says:

    "It’s not like there was a conscious decision "Hey, let’s show a big blank space". It’s just fall-out from the way the code is written."

    Fair enough. Certainly this is something that can be fixed in a service pack or hotfix? Was it? Or is it still there?

  18. GregM says:

    Raymond, is that actual code? I can’t find an ExtractIcon() function that takes only two parameters, and the error checking of the return value for this ExtractIcon doesn’t match the three-argument ExtractIcon function that I did find. Does it really not check any return values, and not check if ExtractIcon returned 1 (if the filename doesn’t refer to an executable, dll, or icon file, or, I assume, is otherwise corrupted)?

  19. Matthew Douglass-Riley says:

    That code doesn’t compile–

    HICON ExtractIcon(

    HINSTANCE hInst,

    LPCTSTR lpszExeFileName,

    UINT nIconIndex

    );

    But the reason for the error is:

    "If this value [nIconIndex] is –1, the function returns the total number of icons in the specified file. If the file is an executable file or DLL, the return value is the number of RT_GROUP_ICON resources. If the file is an .ICO file, the return value is 1."

    so the test for hIco != NULL doesn’t work…

  20. ssobajic says:

    Why can’t the code that loads and display the icon have a check like:
    if(height > some_reasonable_value || height < 0) height = 0;

    Even, why aren’t the icon sizes just hardcoded or rescaled
    automatically to the appropriate size (with a check that the rescale
    makes sense!).

    [I think you completely missed the root cause of
    the bug. A hard-coded icon size doesn’t help if there’s no icon in the
    first place. -Raymond
    ]
  21. While I’m in general in favour of your commenters’ thoughts on forcing program authors to fix bugs, it looks to me almost as though the worst of both sides of the argument is exhibited here. Add/Remove Programs is (correctly, from the "force authors to fix bugs" viewpoint) not bending over backwards to be more tolerant, but instead it’s not making it apparent that the bug is program-caused, and instead making it look *as though* the bug is in A/RP. This means that you don’t get a consistent user experience (which is one of the reasons *to* try and fix user program’s bugs) but also don’t get the benefit of trying to encourage authors to fix the problem, since everyone who looks at it will *say* "A/RP is bugy, there’s a big blank space!" While I’m loath to give advice on a subject that I’m sure I don’t properly understand, I’m thinking in terms of displaying a "broken image" icon (a la the "broken image" from IE), which makes it apparent that the icon in there is somehow wrong to people who use IE (which I am assuming, possibly wrongly, includes most programmers) while still preserving the AR/P window’s correct layout.

  22. Tim says:

    If I google for DisplayIcon on the web I get Raymond’s page as the top link! If I search MSDN (or MSDN online) I get *nothing*. If it wasn’t for third party sites offering registry tips how would you ever know what some of the values in the registry are for? Reverse engineering other apps? That’s fun. It’s even worse though because there are keys you can create (don’t exist by default) that perform quite useful functions. Microsoft thrust the registry upon us but didn’t give us enough information to REALLY use it. If DisplayIcon was documented somewhere (and maybe it is) it would be a LOT easier for developers to use it correctly.

  23. Joku says:

    In this particular case I think the right action is that if there is a problem with the icon, a big red X or equivalent should be shown. Well not Too Big..

    Is this being tolerant? In this particular case no IMHO. This is UI / usability matter. Tolerant thing would be to try show some broken picture say if the you had image file with a header data that contains a separate checksum for the image data and the headers would not be broken while the checksum would show there’s something wrong with the image data itself.

  24. Almost Anonymous says:

    "to "encourage" or "force" some company that’s probably long since moved on to go back and magically deliver patches to everyone using their product."

    Once a behavour has been released it cannot be changed. My point is that Microsoft should, *in the future*, be strict in what it accepts so that these sorts of problems don’t continue to occur.

    Something like "we should display a blank space if the display icon is bad" should never be done. The whole thing should just crap out.

  25. Daniel says:

    So it all boils down to:<b>

    <b>

    (a) an API function that does not return sufficient error information;<b>

    (b) a programmer that made a wrong assumption on the value returned by this API function; and<b>

    (c) people that are not ware of the A/RP conventions and put trash in the registry<b>

    <b>

    I am curious about what would happen should the user move (or remove) the file that contains the icon, as ExtractIcon will return 1…<b>

  26. James Risto says:

    Of course there is no ultimate answer, so we should take the best of the worst. Using logic presented here before; perhaps the alternative is worse. What else could be done? Probe the crappy app somehow, searching for a meaningful icon? Sounds like good money after bad. Display a placeholder? If you did that, and the user had 2 apps in this state, they would end up thinking they had the same app installed twice. My vote; we got the best of the worst now. ARP works the best it can, but is subject to the winds of the crap-app that is not registering itself properly. To me, actually, that blank spot tells me the app is wrong, not ARP.

  27. Chris Wilson says:

    Here’s the thing though: most of the time, end users use A/RP to remove programs. Any behavior in A/RP that makes that simple use case more confusing is counterproductive.

    There have been some suggestions that A/RP should essentially discard (or otherwise complain about) entries with bad icon paths, but that would make it impossible or difficult to accomplish that most common use case: uninstalling the program. After all, even if the original developers did the right thing, the end user may have inadvertantly removed the icon resource file directly from the filesystem, but should they not be able to uninstall the software as a result? (OK, that case is unlikely, but it *could* happen).

    I don’t like the "broken link image" idea because that doesn’t actually give end users any useful information. They don’t care ifthe icon is right, they just want to uninstall the software. Additionally, they may incorrectly deduce that there’s a bigger problem with the software installation itself.

    My vote would be to change the A/RP code so that the old faithful default application icon is displayed when the path in the registry is found to be invalid. Actually, given the relative priority of this bug, I can’t imagine a team ever getting to it, so maybe my vote is just to leave it as is.

  28. Chris Miller says:

    Normally I’m in the camp of not having the OS bend over backwards to fix buggy programs, but this is one of the exceptions to the rule. It’s the end user looking at the A/RP control panel, that person will think this is a A/RP bug, not a bug in the app’s installer registration.

    The other consideration is that the installer part of an application may get less resources thrown at it by the software company. Fixing a cosmetic glitch by the installer will get less priority than issues reported for the app that was installed.

  29. Anonymous Coward says:

    The whole thing should just crap out.

    "If the icon file does not exist in the icon file"…I can see cases where "things happen" and the icon doesn’t exist. You can’t just crash a piece of the OS because the user deleted a dir or the file went away. This is the kind of thing that you can test for but never prevent.

    I’d vote for the default icon being displayed if ExtractIcon fails. Installs are one of the hardest things to do 100% correctly…I really hope I never have to write another one again, but never say never.

  30. Thierry:

    It’s still there. The version of AutoCad we have here causes the problem, and there’s an .REG file on our server to fix it, since it’s REALLY annoying.

    I like to blame AutoDesk for this, since in general I like them less than Microsoft (that’s a bit of an understatement), but I think Microsoft’s code should prevent stupidity like that. In the case of AutoCad, the blank space is easily 3x bigger than the entire list of other programs, which makes the entire dialog practically unusable.

    What app in its right mind would need an icon that big? Worse yet, this is a result of NOT loading an icon? Fixing this wouldn’t be "being tolerant" so much as "being smart."

    Still, I think I’ll continue to blame AutoDesk. I mean, all the other dozens of programs in my list get it right.

    (I’m not sure if newer AutoCad versions have fixed this…and I’m sure my company in no hurry to spend the money to find out…hey Microsoft, why don’t you guys try to enter the CAD market? *wink*)

  31. Thierry:

    It’s still there. The version of AutoCad we have here causes the problem, and there’s an .REG file on our server to fix it, since it’s REALLY annoying.

    Pseudo-Rant:

    I like to blame AutoDesk for this, since in general I like them less than Microsoft (that’s a bit of an understatement), but I think Microsoft’s code should prevent stupidity like that. In the case of AutoCad, the blank space is easily 3x bigger than the entire list of other programs, which makes the entire dialog practically unusable.

    What app in its right mind would need an icon that big? Worse yet, this is a result of NOT loading an icon? Fixing this wouldn’t be "being tolerant" so much as "being smart."

    Still, I think I’ll continue to blame AutoDesk. I mean, all the other dozens of programs in my list get it right.

    (I’m not sure if newer AutoCad versions have fixed this…and I’m sure my company in no hurry to spend the money to find out…hey Microsoft, why don’t you guys try to enter the CAD market? *wink*)

  32. "Microsoft’s code should prevent stupidity like that."

    I wasn’t implying that this needs to be true in every case. The job of the OS is not to make bad programs into good programs. But a good OS should make sure that a bad program doesn’t interfere with good programs.

    In the case of AutoCad’s uninstall taking taking up thousands of pixels in the Add/Remove list, their poor installation testing has caused the Add/Remove Programs applet to be almost completely unusable.

    Microsoft should make sure that, in cases where all programs are affected, no one program can ruin all others. One program should not make it so hard to be able to uninstall other programs.

  33. If a user sees two applications with the same default icon and somehow thinks they are the same, the user has some serious problems. None of these problems can be fixed by code mind you, because if they can’t read the TEXT that says "Application X" and go by the icon, they almost SHOULD get burned for uninstalling the wrong application.

    Icons are fine in A/RP but you know what? They’re unnecessary. You could remove icons entirely and A/RP would be exactly what it needs to be. No AutoCads of the world would take up more real estate and every single item will have it’s own little sandbox to play in.

    What I don’t get is A/RP doesn’t scale good, in fact you can’t resize the window. So why on earth would you allow an icon size that is anything BUT fixed? If your window is fixed, having an icon size that can "possibly" take up the entire size of the window is a very big defect in my mind, but may not be in others.

    I know I’m one of those to say let crappy developers fix their crappy code, but I do thank Microsoft. They handle any problem that even "appears" to be theirs which does say something. I do wish some things would be a little more rigid to somewhat guarantee that Microsoft can say "My code = good. Your code = bad. See!" instead of this "My code = good. Your code = bad, but it looks like my code = bad so I’ll work on your problem until it looks like my code = good."

    Personally I suffer a moral hit when I spend my work hours on someone elses problem, despite what it does to my existing customers or hypothetical platform. I can’t see anyone being that noble for that long before it becomes a complete chore to do anything. It’s one thing to fix something that makes sense for all customers but when it’s your job to please that one customer who effectively gives you the finger, how eager are you going to be to actually get their work done? Not very. Wouldn’t surprise me if nothing is ever done on this. Morale would take a hit for anything other than ripping out the icon code.

  34. Daniel says:

    "Don’t bend over backwards to fix buggy programs; force the program authors to fix their own bugs"

    What if I believe that the wrong test of the value returned by ExtractIcon is a bug in A/RP?

    Jokes aside, I hope this is correct as I will start registering an uninstall icon in my programs and my clueless customers will not be happy if A/RP is broken when they "accidentally" move or delete my icon file.

  35. Daniel says:

    "Don’t bend over backwards to fix buggy programs; force the program authors to fix their own bugs"

    What if I believe that the wrong test of the value returned by ExtractIcon is a bug in A/RP?

    Jokes aside, I hope this is correct as I will start registering an uninstall icon in my programs and my clueless customers will not be happy if A/RP is broken when they "accidentally" move or delete my icon file.

  36. Dave says:

    "Microsoft’s code should prevent stupidity like that."

    That’s a tall order. In this example we’re only dealing with Microsoft stupidity and third-party stupidity. We haven’t even addressed the massive pool of user stupidity that compels people to run email attachments from people they don’t know.

    I do know that it’s a bad idea to fight stupidity with stupidity. Someone above suggested not showing *anything* if the entry wasn’t formatted right. Oh, that would be joy to debug. Now, if it would just blue-screen and show a hex code I could look up on Google, that would work.

  37. MGrier says:

    I think people are missing the severity of the problem. I believe that the number is that of the top 500 apps (don’t ask me which top of which 500 apps) is that 60% of them don’t write their uninstall keys correctly.

    A platform which doesn’t run the software targetted at it won’t be a platform for long.

    Windows has definitely enabled a lot of co-dependency behavior like this in the past and now the problem is that let’s say we got strict for Longhorn. Well you know what, when Longhorn RTMs, based on Douglas Adams’ (or maybe the HHGttG’s) logic on the population of the universe being zero(*), there will effectively be zero software targetting it. Then what? If we force people to rework all their existing and in-development software to target the platform, a lot of the value in developing for Windows has gone down the tubes.

    (*) From http://en.wikiquote.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy:

    "It is known that there is an infinite number of worlds, simply because there is an infinite amount of space for them to be in. However, not every one of them is inhabited. Therefore, there must be a finite number of inhabited worlds. Any finite number divided by infinity is as near to nothing as makes no odds, so the average population of all the planets in the universe can be said to be zero. From this it follows that the population of the universe is also zero, and that any people you may meet from time to time are merely the product of a deranged imagination."

    (The logic is of course flawed and the analogy is weak but what the heck it’s fun)

  38. MGrier says:

    The morale hit of dealing with "junk" like this was traditionally made up for by having a stock price that looks like this:

    http://moneycentral.msn.com/investor/charts/chartdl.asp?Symbol=MSFT&ShowChtBt=Refresh+Chart&DateRangeForm=1&PT=8&CP=1&C5=5&C6=1985&C7=1&C8=2000&C9=2&ComparisonsForm=1&CE=0&CompSyms=&DisplayForm=1&D4=1&D5=0&D7=&D6=&D3=0

    It’s hard to feel that bad about the ugly code you may have written when you’re piloting your 50′ cabin cruiser to your private island. I personally did not enjoy the majority of that wonderful little chart but you have to see how it’s hard to take peoples’ criticism seriously when that’s what your growth looks like. Of course that’s arguably what leads to:

    http://moneycentral.msn.com/investor/charts/chartdl.asp?Symbol=MSFT&ShowChtBt=Refresh+Chart&DateRangeForm=1&CP=0&PT=7&C5=5&C6=1985&C7=1&C8=2000&C9=2&ComparisonsForm=1&CE=0&CompSyms=&DisplayForm=1&D4=1&D5=0&D7=&D6=&D3=0

  39. We wanted a small utility that just corrected these problems in the registry but could not find one. So we just wrote one and published it as freeware. Get it at http://www.christensen-software.com/freeware.htm.

    – Claus

  40. David Candy says:

    Nice how you got your page to work just like Add/Remove with a whopping big space in the middle. Intentional?

    This is a similar problem but doesn’t have the exact symptoms of -1. It’s from a NG post last few days. The guy posted a screenshot here. -1 has pretty much been ruled out as a cause.

    http://myweb.tiscali.co.uk/willer/index.html

    With a -1 the DisplayText appears to start where the icon is normally. This is not the case here. With -1 you still select the entry (it’s just big), not the case here.

  41. Mitheral says:

    Yep AutoCAD having this bug was irritating as hell. Made worse by the fact it was so close to the top of the list. Luckily they have fixed it for 2005.

  42. Fixed in AutoCad 2005? That’s a lot of moolah to shell out to fix it, eh? *grin*

    Maybe if their support website wasn’t such a joke I’d see if there was any mention of it. They probably don’t even care about old versions.

    It’s such an easy fix, too. They could just put an REG file up on their website.

  43. microboy says:

    Previous Microsoft Encarta version also has this problem…

Comments are closed.