The case of the auto-hide taskbar


A customer reported that their taskbar would sometimes spontaneously go into auto-hide mode. What made this particularly insidious was that they had deployed a group policy to prevent users from changing the auto-hide state (because they never wanted the taskbar to auto-hide), so when the taskbar went into auto-hide mode, there was no way to get it out of that mode!

The customer's first investigation was to find out where the auto-hide state was recorded. A little bit of registry spelunking (because as far as these people are concerned, everything is in the registry) showed that a single bit in the StuckRects2 registry value controlled the auto-hide setting. They used Process Monitor and observed that it was Explorer that was updating the value. That was as far as they could troubleshoot the problem and came to the Windows team for further guidance.

It turns out that watching the registry value get updated doesn't tell you anything interesting. Explorer always writes that value when you log off, and the value written is the taskbar's current auto-hide state. The real culprit is the person who changed the taskbar's state, causing Explorer to save the updated state at logoff. And that culprit is somebody who called SHApp­Bar­Message with the ABM_SETSTATE parameter, in order to turn on the ABS_AUTOHIDE bit.

I warned you many years ago that the auto-hide and always-on-top states are user settings, and programs should modify them only under the instructions of the user.

The support technician was able to put together an instrumented version of the SHApp­Bar­Message function that logged any attempt to put the taskbar into auto-hide mode. (This step took a little while because the first attempt wasn't quite right and ended up not working.)

A few days later, the support technician reported back: The culprit was found with his hand in the cookie jar! One of the applications the customer was using was indeed calling SHApp­Bar­Message with the ABM_SETSTATE parameter, and passing the ABS_AUTOHIDE flag to make the taskbar auto-hide, and the application never called the function again to restore it back to normal. Result: Taskbar goes to auto-hide and stays there.

Mind you, even if the application remember to set the auto-hide flag back to its original value, that still wouldn't have been the correct solution. Suppose two programs did this.

bool fWasTaskbarAutoHide;

OnStartup()
{
    fWasTaskbarAutoHide = GetTaskbarAutoHideState();
    SetTaskbarAutoHide(true);
}

OnExit()
{
    SetTaskbarAutoHide(fWasTaskbarAutoHide);
}

The user first runs the other program, which remembers that the taskbar is not auto-hide, then sets it to auto-hide. Now the user runs your program, which remembers that the taskbar is auto-hide, and then sets the taskbar (redundantly) to auto-hide. The user exits the first program, which sets the taskbar to normal. Now the taskbar is in normal state even though the your program wants it to be auto-hide. Finally, your program exits, and it "restores" the taskbar to auto-hide.

This is just another case of using a global setting to solve a local problem. The local solution is to create a fullscreen window, and the taskbar will get out of the way automatically.

The customer went to the online support forum for the program that was setting the taskbar to auto-hide and forgetting to restore it. And, how about that, there was a thread in that forum called something like "After I run Program X, my taskbar gets set to auto-hide."

Bonus reading: How your taskbar auto-hide settings can keep getting overwritten. It seems this problem happens a lot. This is the sort of problem you get when you decide to expose a user setting programmatically: Applications start messing with the setting when they shouldn't.

Comments (43)
  1. Danny says:

    Slow day, huh Ray? Everything you wrote here is variation of something you already wrote and all the links are pointing to former posts. So how about a dream? They seem interesting.

    [I thought it was interesting that the same problem occurred more than once. I wrote up the second occurrence, then went to hook up links and realized that this happened once before. There are multiple lessons here. (1) The problem at hand. (2) The fact that the same problem occurs more than once. (3) That most of the time, solving problems consists of applying information you already know. (4) Copying Mark Russinovich's popular "the case of" model doesn't mean you will be as popular as he is. -Raymond]
  2. Rick C says:

    There's a game out there that tries to create a full-screen window, but disables the restore and maximize buttons.  Something about it confuses Explorer, at least on Windows 8, such that the window goes behind the taskbar.  Wouldn't be so bad except that it likes to place buttons so that only 2-3 pixels of them are not covered by the taskbar.  You might say it's not very Civilized.

  3. Sadly, this is too frequent. I have a relatively large list of companies whose software is banned from my computers (and from the ones of my customers that are managed by me) because they do things they are not supposed to do, or because they do things at your back, without warning or prompting. In that list there are a couple of big companies whose software can be found on almost every Windows computer, because of their "update services". You know which ones I am talking about :-) .

  4. Anon says:

    @Ray

    Also, don't listen to the trolls. These are some of the best articles.

  5. Mc says:

    The way lots of people learn stuff is through repetition…

  6. Marc K says:

    I'd actually be interested in more information about the "instrumented version of the SHApp­Bar­Message." This sounds like it could be a good technique to troubleshoot a whole range of issues.

    [The support technician made a change to shell32.dll, recompiled it, and deployed it to the customer's machine. Recompiling shell32 is not something most people can do. -Raymond]
  7. Jack B Nimble says:

    And here I thought the story was going to end with the program in question having been developed by the customer with the issue.

    "oh, uh, we need that application to hide the task bar…"

  8. There's also another problem with taskbar auto-hide. Since its dawn in Windows 95, sometimes it happens that the taskbar refuses to hide. The auto-hide option is still on, and the taskbar is annoyingly covering parts of other programs (e.g. status bars).

    What helps is to click on ALL taskbar buttons, including tray icons. Usually one of them is the culprit, but it's hard to guess which one.

  9. alexx says:

    Speaking of programs that change global settings, once I had to patch a well-known modem's software that change "show window content while dragging" setting while it is running, probably just so it can hide the flickering while its window is resized.

  10. Why does explorer write-on-exit instead of writing-on-change?

    [Batching up writes is generally considered to be a good thing. -Raymond]
  11. JM says:

    @Maurits: what possible value would it have to record the change during the session? This is not exactly transactionally sensitive information that must be preserved across a crash. It only needs to be preserved across sessions, and that's what Explorer does. I can imagine Explorer has a bunch of things it needs to record like that, and saving them all in one gulp at the end probably saves some cycles.

  12. Joshua says:

    [The support technician made a change to shell32.dll, recompiled it, and deployed it to the customer's machine. Recompiling shell32 is not something most people can do. -Raymond]

    In /this/ case, it would just take a good bit of assembly. Add a new CODE section, move the entry point to the new section, log the call and jump to the original entry point. Don't forget to add two more fixups.

  13. Surly says:

    "This is the sort of problem you get when you decide to expose a user setting programmatically: Applications start messing with the setting when they shouldn't."

    Because microsoft knows best and having a system in place to control access (allowing both fin-grained and broad control) to such api's is unthinkable, isn't it?

    Oh wait, isn't UAC exactly such a system, although a very poorly implemented one?

    Don't even get me started on the settings not even the user have access to.

    Why are users not allowed to change them? Microsoft answers: Because our users are illiterate morons that cant read instructions before their monkey fingers starts hammering on every single setting randomly (and we make more money by herding the sheep).

    Microsoft making the decisions for the user is like a baker telling the wedding planner: "This is how the wedding cake will look and taste like, no you can not change it, this is the best shape and taste for a wedding cake according to my opinion, business plan and vaguely collected unverifiable statistics"

    As the wedding planner i would go to another baker but there exists no other baker that does cakes for a wedding so yeah.

    The baker invents something great than suddenly out of some reason presumably greed turns around and shafts its loyal customers that liked what the baker used to stand for. (Freedom of choice, etc)

  14. Dave G says:

    "[The support technician made a change to shell32.dll, recompiled it, and deployed it to the customer's machine. Recompiling shell32 is not something most people can do. -Raymond]"

    How hard is it to pull the source code from the repo, make the changes and press compile?

    (Compile as in send code with changes to a build machine which does the compilation).

    Please don't tell me microsoft still use custom flaky make scripts that only the one that wrote it can barely understand or know how to use?

    Afterthought: Is this why it takes so long for microsoft to come out with updates and new windows versions?

    I thought it was because NSA was slow at responding to e-mails.

  15. Jon says:

    @Surly

    A baker can use their expertise and interact with the customer for each cake to determine how to make what the customer wants, and to steer them away from ideas that simply won't work.

    The Microsoft bakery has to publish a brochure with all the possible cake options. It has to carefully test every possible combination of options to make sure that every cake will taste good and not fall apart. If a customer orders some unusual combination they didn't expect, they have to produce exactly what was specified, even if it is a horrible cake, and take the blame for it. When they update the brochure with new cake options, they can't revise it to make it so you can't order that horrible cake, because the customer has found a way to repurpose them as halloween decorations or something and will throw a fit when they are no longer available and the new nice cakes aren't backwards-compatible with his halloween decorating business.

    I don't think the bakery analogy works for operating systems.

  16. alegr1 says:

    [The support technician made a change to shell32.dll, recompiled it, and deployed it to the customer's machine. Recompiling shell32 is not something most people can do. -Raymond]

    Would not a conditional breakpoint be able to do that?

    [As I recall, this issue was reported by the customer's employees, so it was presumably deployed to a few thousand machines, none of whose users know how to use a debugger. -Raymond]
  17. alegr1 says:

    Now if only Windows stopped to fudge SPI_GETWORKAREA while disconnected and after reconnecting to the console… It's very frustrating to have IE/other app to be obscured by the taskbar and not being able to recover that.

  18. alegr1 says:

    >Microsoft answers: Because our users are illiterate morons that cant read instructions before their monkey fingers starts hammering on every single setting randomly (and we make more money by herding the sheep).

    There is more truth to that that you realize. Not in the users' favor.

  19. voo says:

    @Dave G: While writing your snarky comment you sadly missed to oh so much more obvious reason for why "most people" can't recompile shell32.

    Or did MS open source their OS while I wasn't looking?

    @Surly: "Because microsoft knows best and having a system in place to control access (allowing both fin-grained and broad control) to such api's is unthinkable, isn't it?"

    Umn and now go ahead and tell us how you plan to actually implement this system to control access to those APIs. Because you know it's pretty hard to keep the user and a determined enough programmer apart. If you manage to come up with a working solution I'm sure MS would be very happy about that.

    @alegr1: Rather more complicated for the users having to step through the assembly and reverse engineering the code considering that the customer doesn't have the source code. This way they just have to replace some file, let the machine running for a while and then check a log file – seems more convenient and easy.

  20. Nick says:

    > The support technician made a change to shell32.dll, recompiled it, and deployed it to the customer's machine.

    I've not done a lot of it, but wouldn't creating a simple logging window hook for the taskbar be easier and more flexible (or already exist)?  Though maybe adding a single line to OutputDebugString in shell32 isn't too hard (or maybe it is, if it took multiple tries!) :)

    I admit wondering why there's never been a flag added to explicitly indicate that a window is supposed to be full-screen and instead relying solely on the implicit guessing done by Explorer.  I've seen it fail for whatever reason often enough (for example, when a certain browser's plugin for flashy content tries to show full-screen video with the Windows DPI setting increased).

    @Jon

    Most analogies fall down if you poke them hard enough.  I think Surly has a point, though; if someone wants a cake with blue carrot cake and pink spearmint frosting topped with Red Hots, the baker should oblige (or lose the customer's business).  A tightly-controlled walled garden approach is attractive to companies because overall it's cheaper (and recently become acceptable and even fashionable), but it just doesn't fly on desktops.  This is because of the reason you gave: it's impossible to anticipate all of the myriad of ways the system will be used.

    [The log would say "Explorer.exe. Explorer.exe. Explore.exe. Explorer.exe…" -Raymond]
  21. mpz says:

    @alexx: Oh god, I know exactly what software you're talking about. I solved the problem by creating a Dial-Up Networking config that connects to the Internet, and then used MDMA with a certain AT command to disable the virtual CD drive that either starts up the software install process or forcibly launches said software (ie. makes the device appear as a modem, as it should). MDMA /hwstorage:0 disables the virtual CD-ROM device. Now I can connect to the Internet without having my graphics options mucked with.

  22. Surly says:

    @Jon

    "The Microsoft bakery has to publish a brochure with all the possible cake options. It has to carefully test every possible combination of options to make sure that every cake will taste good and not fall apart."

    Have you not heard of standard recipes that bakers offer?

    They are standard recipes known to be good that can be customized if needed based on bakers suggestions and customers taste.

    "If a customer orders some unusual combination they didn't expect, they have to produce exactly what was specified, even if it is a horrible cake, and take the blame for it."

    Bakers take custom orders all the time. Take birthday cakes shaped as genitals for a good example.

    The baker offers a service. That service is to bake for the customer. It is quite clear.

    While the baker can make suggestions that might fit the customers need better, in the end it is up to the customer.

    The service is clear: it is to bake for the customer and not judge the customers taste.

    Microsoft offers..offered the same sort of service. The service was clear. The customer knew what microsoft offered.

    Then microsoft made the service they offered unclear, fuzzy and began to order the customer around, telling them what they could and couldn't have.

    Microsoft went retard as the expression goes and tried to fix something that was not broken.

    In a service there will always be bad customers that whine about everything. That cannot be helped.

    Although microsoft thought they could do the impossible. Make everyone happy.

    Instead of taking the blame from the bad customer as for what it was microsoft did something horrible, that lacks the most simple of common sense in a business, unthinkable. Microsoft listened to the blame and changed based on it. The result: all good customers when WTF?! and started to complain. Suddenly microsoft with its inflated-ego hurt, went no i will not change again, the previous change costed much money. The change is final.

    "When they update the brochure with new cake options, they can't revise it to make it so you can't order that horrible cake, because the customer has found a way to repurpose them as halloween decorations or something and will throw a fit when they are no longer available and the new nice cakes aren't backwards-compatible with his halloween decorating business."

    Everyone gets upset when their favorite ice-cream flavor gets removed. Especially when the flavor that replaced it tastes horrible.

    Bakery analogy works well i think.

  23. J Walroth says:

    "(4) Copying Mark Russinovich's popular "the case of" model doesn't mean you will be as popular as he is."

    Mark got popular because he showed how bad microsoft was at coding and handling issues and feedback.

    This blog post only shows how bad microsoft is at informing and educating the developers about when and how to use the api's.

    To third-party developers this is a sore subject. You should have expected some frustrated regurgitation's from devs getting reminded.

    To be fair since Mark joined microsoft it is as if he died.

    Mark have stopped making good and interesting blog posts.

    I actually thought Mark had died for a short period because Marks activities stopped so abruptly.

    Sort of proves that if you join microsoft you die inside as if it sucks you dry of some vital fluid needed for making interesting and useful things.

    "the case of" model works well if the case is interesting and hard to deduce.

    Marks model also used to provide solutions that the user could do themselves.

    Recompiling shell32 is not something a user could do themselves.

    This would have been an interesting post if you had provided a way for the user to track down such an issue themselves.

    The devil is in the details and the delivery.

  24. steven says:

    I know you don't allow speculation about which program "Program X" really is, but what I'd be interested to know is whether the creators of "Program X" actually ended up doing the right thing and fixing their stuff?

  25. Nick says:

    > [The log would say "Explorer.exe. Explorer.exe. Explore.exe. Explorer.exe…" -Raymond]

    Well clearly this Explorer.exe needs to be terminated before it causes any further harm!

    Ha ha, oops.

  26. Raphael says:

    Of course, it would be really great if group policy would actually prevent the user from toggling the setting it's protecting instead of just locking down explorer. Would it really be so hard to block the corresponding API calls and registry keys?

    [Often, you want to block the behavior only at the UI level and not the API level. For example "block access to the C drive" is a UI level block, because if it were an API level block you couldn't even boot the computer. -Raymond]
  27. Gabe says:

    There are conditions where it is appropriate to batch up changes and save them all at once. In Explorer's case, though, most changes are infrequent and the only way to save them includes closing all your applications.

    Since my use case for Explorer is one where I log on, and stay logged on until the computer crashes or loses power (or Explorer crashes or my RDP session is terminated due to idle timeout), my settings never get saved. If I want some settings saved, I have to make the change, log off, log back on, and restart whatever apps I had running.

    In a more pathological case, I often deal with workstations whose states are "frozen". That is, changes made to the filesystem are stored in memory or some separate disk, and only applied when some special action is taken to "thaw" the system.

    So ideally you would "thaw" the system, make your settings change, and "freeze" it again. Instead, you have to "thaw" the system, make your settings change, log off, log back on, and "freeze" the system.

    Even if it did have to batch settings changes, it would be nice if it could do it periodically instead of just when logging off, so that after a crash my settings didn't revert to what they were 6 months ago.

  28. Anon says:

    Speaking of the taskbar…

    I reported this years and years ago, I think when we got our first "Whistler"-branded XP beta discs, but if you right-click and application in the locked taskbar and then drag the taskbar, which is easier to accidentally do than one might first think, it will dock to the top of the screen regardless of lock state.

    This also causes the desktop and all opened windows to rearrange themselves, which can be EXTREMELY irritating if you're using, say, a CAD application that needs to refresh a render when the window is moved.

    I really wish that had been fixed in Win7. I guess fixing it in Win8 was better than nothing, for those who think Win8 is etc. *rimshot*

  29. ulric says:

    often time you can't educate developers about something like this, because it's a program manager that's asking for the taskbar to be turned to autohide, and that's the end of that discussion. sometimes it's even sales.  if there wasn't an api, some wm command message would be sent somewhere.

  30. Yuhong Bao says:

    @Joshua: There is still the issue of how to satisfy WFP.

  31. Neil says:

    Why does Explorer even persist the SHAppBarMessage state, rather than just the state of the checkbox?

    [You're assuming that the SHAppBarMessage state is different from the checkbox state. Imagine if that were true. "My taskbar is auto-hiding, but when I look at the properties, auto-hide is unchecked. What's going on?" -Raymond]
  32. @Nick: what is a full-screen window is well documented: just create a borderless window (use WS_POPUP) that exactly covers the entire screen.

  33. John Doe says:

    The trolling rate is exponentially proportional to the repeated topics. This may be a correlation between the sum of the old trolls plus the new ones which are as many as the old ones. All of them are just waiting for an oportunity to unleash their ire on-topic (troll doesn't mean mindless beast, only beast).

    @Raymond, batching up writes is a good thing if you have huge amounts of data to write. Nevertheless, you should write as soon as feasibly possibly, such as when a buffer is full or after some time without writes.

    This is just delaying writes as much as possible (in this case, the lifetime of the process, and even so, only if it terminates cleanly), which is a bad thing. I bet that, even though all write operations happen when Explorer is quitting, each registry value is written individually, most probably not in a transaction.

    There's also this duality: file type (e.g. extension) settings are written on demand, but other preferences aren't (or are they? perhaps some are, others aren't), even though they're all under the same dialog (in this case, Folder Options).

    Contrast with Internet Explorer, Office, Visual Studio et al, that write configurations when the user presses OK. To be fair, I bet these applications also have similar problems, but not as a general rule.

    @JM, about sessions, I've experienced configuring Explorer, using Windows for a few hours and the power went down. When power was restored and I rebooted the computer, most of my Explorer settings were forgotten.

  34. Raphael says:

    Ok, *some* group policy settings would be hard to implement in an actually useful manner. But you can't even effectively block your users from changing the wallpaper without removing Firefox.

    [Well, because if you blocked it at the API level, how would the IT department's "set_the_wallpaper_to_the_official_wallpaper.exe" logon script be able to set the wallpaper to the company standard wallpaper? -Raymond]
  35. alegr1 says:

    All these issues with arrogant/malicious/ignorant programs changing some global state just prove that Microsoft is too late with a concept of application isolation. An application without an appropriate signature should not have access to system-global or user-global state, even when run in the administrator login session. Especially if it's a plugin, like friggin Java, which was a reason my daughter got a ransomware a few days ago. Luckily, it only was a user account (not an admin) and I was able to mount the user's hive and clean the program from user's Run key.

    [You need to get in a room with the people who say "It's my computer, I should be able to write a program to do whatever I want" and let me know who wins. (Even if you say "Only Explorer can change this setting", all somebody has to do is inject code into Explorer.) And if things worked the way you wanted, you wouldn't have been able to mount the user's hive (because that's global state). -Raymond]
  36. xpclient says:

    "Why does explorer write-on-exit instead of writing-on-change?"

    @Maurits, IIRC, in Windows 7 MS made some change so Explorer saves settings more often, not just on exit.

  37. alegr1 says:

    [You need to get in a room with the people who say "It's my computer, I should be able to write a program to do whatever I want" and let me know who wins.]

    Which are 0.01% of all users. Are people still jailbreaking iPhones?

  38. Nick says:

    > Which are 0.01% of all users.

    First, it's more than that and second, it's that many *now*.  When you take away 75% of the Windows tools and utilities and programs people use every day that number will go up, and fast.  PS: The filesystem is "global state".  Now my programs can't share files.

    > Are people still jailbreaking iPhones?

    Yes.

  39. 640k says:

    @alex: Speaking of programs that change global settings, once I had to patch a well-known modem's

    software that change "show window content while dragging" setting while it is running, probably

    just so it can hide the flickering while its window is resized.

    This is unfortunately a common problem with most commercial remote desktop applications. Take a

    look at the big company which has a terminal server-like product, their client does the same,

    programmatically changes the window content redraw setting. I found it so irritating I had to

    develop an util which resets it back to default as fast as it changes.

    @Raymond: Often, you want to block the behavior only at the UI level and not the API level.

    This is contrary what you have claimed earlier, that the user should be in control, not applications.

    A setting should at least be changeable in the standard gui by the user, if an app the user executes can change it.

    @Raymond: Well, because if you blocked it at the API level, how would the IT department's

    "set_the_wallpaper_to_the_official_wallpaper.exe" logon script be able to set the wallpaper

    to the company standard wallpaper?

    GPOs should be distributed by accounts that has admin rights on computers, not by simple user accounts.

    This might be a fundamental flaw in windows/AD though. In general, trying to set things at login time,

    running as a user, should not be allowed in many cases. Ordinary users should not be able to change lots

    of settings.

    @alegr1: You need to get in a room with the people who say "It's my computer

    They have to be admins then, not ordinary users. And they should be accountable if anything screws up,

    like desktop settings. At a company they will have to fix it in there spare time, or pay some admin to do it.

    [Administrative policy beats user preference. In the wallpaper case, the policy is implemented by Explorer, and Explorer uses (ta daa) the wallpaper API to change the wallpaper. If you blocked the API, then how would Explorer set the wallpaper according to policy? -Raymond]
  40. John says:

    Sorry if this is a repost, I didn't get a post confirmed from the software:

    It's always interesting to read these topics as it seems to be a popular one for the trolls.

    It comes down to a never ending battle of walls and ladders as Raymond has mentioned so many times before. The way I see it is you either: Give too much leeway and people complain that the system is unstable and its Microsoft's fault -or- lock it down too much and people complain that its anti-competitive/tin-foil hats come out in force. You're damned if you do, damned if you don't.

    As usual the truth lies somewhere in the middle, the best solution I think is to attempt to educate users (through blog posts such as this) that explain the issue and give people the tools to start the name and shame game. Microsoft (and Raymond) has chosen not to participate in this game (as is their right) but nothing is preventing the end users from starting a blog or database of known "poorly written software".

  41. Joshua says:

    [Administrative policy beats user preference.]

    Another pointless wall. Read the sysinternals blogs. GPO falls to a competent local admin.

  42. Wisefaq says:

    @Joshua

    "GPO falls to a competent local admin"

    Most security blocks fail if you already have local admin rights.

  43. Roman says:

    > The local solution is to create a fullscreen window, and

    > the taskbar will get out of the way automatically.

    Sure… except when it doesn't.

    I think the reason people do this is because this feature is, to this day, not 100% reliable (like many things with Explorer… for example desktop icon positions).

Comments are closed.

Skip to main content