October, 2005

  • The Old New Thing

    When programs assume that the system will never change, episode 1

    • 100 Comments

    An example, all too frequent, of ways programs assume that the user interface will never change is reaching into system binaries and sucking out undocumented resources. In the shell, we have fallen into the reluctant position of carrying "dead" icons around for the benefit of programs that assumed that they would always be available. However, we often make these "orphaned" icons blank so that these programs don't crash, but they don't necessarily look all that wonderful either.

    Recently, I learned of a new type of resource stealing: Stealing animations. For Windows Vista, there have been many changes to the way the system internally organizes its resources in order to support the Multilingual User Interface feature. One of the things we found was a handful of programs that reach directly into Shell32.dll in order to obtain the file copy animation. Too bad (1) the animation isn't kept there any more, and even if we moved the animation back to its original location, (2) the animation uses a new compression scheme that older programs can't handle.

    Remember, resources in system DLLs should be treated as implementation details, unless explicitly documented otherwise.

    I'm not sure what we're going to do about the animation resource problem. Suggestions anyone? Should we declare these programs broken and make the people who bought them go back to their vendors for upgrades? (What if there is no vendor?) Should we develop a shim and hope that those four are the only programs that need it? Should we carry the original animation in shell32.dll as junk? If I told you that one of the programs that did this won "Game of the Year" recently, would that change your answer? What if another turned out to be a top-rated anti-spyware program?

  • The Old New Thing

    There's something about Rat Poker

    • 56 Comments

    When performing usability tests, one of the standard tasks we give people is to install a game, and the game we usually use is The Puzzle Collection. (Yes, it's an old game, but continually updating the game makes it less valid to compare results from one year to the next.)

    One of the things that the game's Setup does that always confuses people is that it asks you where you want to install it and suggests a directory. If you accept the default, a warning box appears that reads, "The directory C:\Program Files\Microsoft Puzzle Collection does not exist. Do you wish to create it?"

    People see this dialog box and panic.

    Why?

    Because it's an unexpected dialog, and unexpected dialogs create confusion and frustration. From a programming perspective, this is a stupid dialog, because of course the directory doesn't exist. You're installing a new program! From a usability point of view, this is a stupid dialog, because it makes users second-guess themselves. "Gosh, did I do something wrong? The computer is asking me if I'm sure. It only does that when I'm about to do something really stupid." They then click "No" (it's always safest to say No), which returns them to the dialog asking them to specify an installation directory, and they'll poke around trying to find a directory that won't generate an "error message". I've seen users install the Puzzle Collection into their Windows directory because that was the first directory they could think of that didn't generate the "error message".

    Anyway, after the program is installed (one way or another), we tell them to relax and play a game. We say it as if we're giving them a reward for a job well done, but it's actually still part of the test. We want to see how easily users can find whatever it is they just installed.

    One thing you can count on is that when faced with the collection of games available, for some reason, they always pick Rat Poker.

    Always.

    Each of us has our own pet theory why people always pick Rat Poker. Personally, I think it's that the Rat Poker icon is the most friendly-looking of the bunch. Many of them are abstract, or they depict scary creatures, but awww look at that cute rat with the big nose. He looks so cheerful!

    Click. Another vote for Rat Poker.

  • The Old New Thing

    Even in the enlightened year of 2005, we have programs that don't handle long file names

    • 42 Comments

    When I saw Tim Sneath's description of the root cause for all the Windows Vista product key problems, I was amazed that the reason was something my readers tend to go completely ballistic over: Long file names.

    It so happens that one of the ISO mounting tools that people were using for installing Windows Vista doesn't support long file names! (At least not by default.)

  • The Old New Thing

    Running old programs in a virtual machine doesn't necessarily create a good user experience

    • 37 Comments

    Many people suggest solving the backwards compatibility problem by merely running old programs in a virtual machine. This only solves part of the problem.

    Sure, you can take a recalcitrant program and run it in a virtual machine, with its own display, its own hard drive, its own keyboard, etc. But there are very few types of programs (games being a notable example) where running them in that manner yields a satisfying experience. Because most programs expect to interact with other programs.

    Since the virtual machine is running its own operating system, you can't easily share information across the virtual machine boundary. For example, suppose somebody double-clicks a .XYZ file, and the program responsible for .XYZ files is set to run in a virtual machine.

    • Start the virtual machine.
    • Log an appropriate user on. Hopefully, the user has an account in the virtual machine image, too. And of course the user will have to type their password in again.
    • Once the system has logged the user on, transfer the file that the user double-clicked into the virtual machine's hard drive image somehow. It's possible that there are multiple files involved, all of which need to be transferred, and the identities of these bonus files might not be obvious. (Your word processor might need your spelling exceptions list, for example.)
    • Run the target program with the path to the copied file as its command line argument.
    • The program appears on the virtual machine operating system's taskbar, not on the main operating system's taskbar. Alt+Tab turns into a big mess.
    • When the user exits the target program, the resulting file needs to be copied back to the main operating system. Good luck dealing with conflicts if somebody changed the file in the main operating system in the meanwhile.

    The hassle with copying files around can be remedied by treating the main operating system's hard drive as a remote network drive in the virtual machine operating system. But that helps only the local hard drive scenario. If the user double-clicks a .XYZ file from a network server, you'll have to re-map that server in the virtual machine. In all cases, you'll have to worry about the case that the drive letter and path may have changed as a result of the mapping.

    And that's just the first problem. Users will expect to be able to treat that program in the virtual machine as if it were running on the main operating system. Drag-and-drop and copy/paste need to work across the virtual machine boundary. Perhaps they get information via e-mail (and their e-mail program is running in the main operating system) and they want to paste it into the program running in the virtual machine. International keyboard settings wouldn't be synchronized; changing between the English and German keyboards by tapping Ctrl+Shift in the main operating system would have no effect on the virtual machine keyboard.

    Isolating the program in a virtual machine means that it doesn't get an accurate view of the world. If the program creates a taskbar notification icon, that icon will appear in the virtual machine's taskbar, not on the main taskbar. If the program tries to use DDE to communicate with Internet Explorer, it won't succeed because Internet Explorer is running in the main virtual machine. And woe unto a program that tries to FindWindow and then SendMessage to a window running in the other operating system.

    If the program uses OLE to host an embedded Excel spreadsheet, you will have to install Excel in the virtual machine operating system, and when you activate the object, Excel will run in the virtual machine rather than running in the main operating system. Which can be quite confusing if a copy of Excel is also running in the main operating system, since Excel is a single-instance program. Yet somehow you got two instances running that can't talk to each other. And running a virus checker in a virtual machine won't help keep your main operating system safe.

    As has already been noted, the virtual machine approach also doesn't do anything to solve the plug-in problem. You can't run Internet Explorer in the main operating system and an Internet Explorer plug-in in a virtual machine. And since there are so many ways that programs on the desktop can interact with each other, you can think of each program as just another Windows plug-in.

    In a significant sense, a virtual machine is like having another computer. Imagine if the Windows compatibility story was "Buy another computer to run your old programs. Sharing information between the two computers is your own problem." I doubt people would be pleased.

    For Windows 95, we actually tried this virtual machine idea. Another developer and I got Windows 3.1 running in a virtual machine within Windows 95. There was a Windows 3.1 desktop with Program Manager, and inside it were all your Windows 3.1 programs. (It wasn't a purely isolated virtual machine though. We punched holes in the virtual machine in order to solve the file sharing problem, taking advantage of the particular way Windows 3.1 interacted with its DPMI host.) Management was intrigued by this capability but ultimately decided against it because it was a simply dreadful user experience. The limitations were too severe, the integration far from seamless. Nobody would have enjoyed using it, and explaining how it works to a non-technical person would have been nearly impossible.

  • The Old New Thing

    Newark Liberty International Airport Terminal A travel tips

    • 35 Comments

    The line for going through the security checkpoint at Terminal A of Newark Liberty International Airport splits into three lines after you get through the ID check. When you get to the decision point, they all look the same, but don't be fooled.

                 ID  / 3 ----------------------------------X
    >>>-----------|--  2 ------------------------X
               check \ 1 -------------X
    

    Take line 1. As you can see, it is a much shorter wait than the others.

    If you observe carefully as you get into line, you'll see that all the people in business suits are in line 1. That's because the business travelers know this secret and the tourists don't.

    The lines are uneven due to space constraints. In reality, the corridor looks more like this:

                 ID  / 3 -----------------------------------XXXXXXXXX---
    >>>-----------|--  2 ------------------------XXXXXXXXX  XXXXXXXXX 
               check \ 1 -------------XXXXXXXXX  XXXXXXXXX--------------
                                      XXXXXXXXX-------------------------
    

    (I still call it Newark International Airport, since that's the name it had when I lived in New Jersey.)

  • The Old New Thing

    The undeletable Outlook folder

    • 35 Comments

    For a while, I've had a few "undeletable Outlook folders". Even after deleting all the messages from them, Outlook just complains when I try to delete them. There was some sort of error message, but of course I didn't read it. The only option was OK, so I clicked it. As I recall, the message said something about "Can't delete because blah blah pending synchronization blah blah." I don't know what "pending synchronization" is, but it must be important if Outlook won't let me delete a folder because of it.

    Meanwhile, I also noticed that my Sync Issues folder grew by about a dozen error messages every day, and I had to go clean them out every so often. The messages looked something like this:

    9:26:59 Synchronizer Version 11.0.6352
    9:26:59 Synchronizing Mailbox 'Raymond Chen'
    9:26:59 Synchronizing local changes in folder '0618'
    9:26:59 Error synchronizing folder
    9:26:59		 [80004005-501-4B9-0]
    9:26:59		 The client operation failed.
    9:26:59		 Microsoft Exchange Server Information Store
    9:26:59		 For more information on this failure, click the URL below:
    9:26:59		 http://www.microsoft.com/support/prodredirect/outlook2000_us.asp?err=80004005-501-4b9-0
    9:27:00 Synchronizing local changes in folder '0611'
    9:27:00 Error synchronizing folder
    9:27:00		 [80004005-501-4B9-0]
    9:27:00		 The client operation failed.
    9:27:00		 Microsoft Exchange Server Information Store
    9:27:00		 For more information on this failure, click the URL below:
    9:27:00		 http://www.microsoft.com/support/prodredirect/outlook2000_us.asp?err=80004005-501-4b9-0
    9:27:01 Done
    

    I clicked the link to obtain further information, but the instructions there didn't solve my problem. I just chalked this up to "Outlook gets that way sometimes," and ignored the messages, since they didn't seem to be hurting me. I had almost resigned myself to carrying these two undeletable folders with me until I die.

    Then today I randomly stumbled across the solution.

    I right-clicked one of the "stuck" folders and selected "Clear Offline Items", even though there were no offline items in the folder. (I deleted all the messages from it; the folder was empty. How do you clear something that is empty?) I got a warning dialog that said something like, "Hey, there's some unfinished synchronization here, do you want to clear the items anyway?" I said, "Go for it."

    And then Outlook let me delete the folder.

    My guess is that Outlook's synchronization engine got wedged up on these two folders because there was some unfinished business that it just couldn't reconcile, and it said, "Eh, maybe it'll work tomorrow, but in the meantime, don't delete it yet. I'm still working on it." Repeat for several months, because tomorrow never comes. By telling Outlook, "Oh just give up already, trust me, I don't care any more," the synchronization engine released its objections to deleting the folder and let me finally wipe it out.

    If you have a mysteriously undeletable folder, you could try this, see if it helps.

    Update: I just hit the problem again. The error message is

    Outlook hat die Synchronisierung der lokalen Änderungen an Elementen in diesem Ordner noch nicht abgeschlossen. Der Order kann erst nach Abschluss der Synchronisierung mit dem Server gelöscht werden.

    Yes, I run Outlook in German. This translates to "Outlook has not yet completed the synchronization of local changes to items in this folder. The folder can only be deleted after completion of the synchronization with the server."

    This time, deleting the offline items wasn't good enough. Even though the Properties dialog says "Server folder contains: 0 items" and "Offline folder contains: 0 items", I nevertheless had to trigger a manual synchronization to reconfirm that zero equals zero before it would let me delete the folder.

    (Watch, people are now going to start sending me Outlook product support questions. Hey, I don't work on Outlook. I'm a hapless victim like you!)

  • The Old New Thing

    Consequences of the scheduling algorithm: Low priority threads can run even when higher priority threads are running

    • 31 Comments

    Just because you have a thread running at a higher priority level doesn't mean that no threads of lower priority will ever run.

    Occasionally, I see people write multi-threaded code and put one thread's priority higher than the other, assuming that this will prevent the lower-priority thread from interfering with the operation of the higher-priority thread so that they don't need to do any explicit synchronization.

    BOOL g_fReady;
    int g_iResult;
    // high priority thread
    SetResult(int iResult)
    {
     g_fReady = TRUE;
     g_iResult = iResult;
    }
    
    // low priority thread
    if (g_fReady)
    {
     UseResult(g_iResult);
    }
    

    Let's ignore the cache coherency elephant in the room. If there were a guarantee that the low priority thread will never ever run while the high priority thread is running, this code looks okay. Even if the high priority thread interrupts and sets the result after the low priority thread has checked the ready flag, all that happens is that the low priority thread misses out on the result. (This is hardly a new issue, since the principle of relativity of simultaneity says that this was a possibility anyway.)

    However, there is no guarantee that the low priority thread can't interfere with the high priority thread.

    The scheduler's rule is to look for the thread with the highest priority that is "runnable", i.e., ready to run, and assign it to a CPU for execution. To be ready to run, a thread cannot be blocked on anything, and it can't already be running on another CPU. If there is a tie among runnable threads for the highest priority, then the scheduler shares the CPU among them roughly equally.

    You might think that, given these rules, as long as there is a high priority thread that is runnable, then no lower-priority thread will run. But that's not true.

    Consider the case of a multi-processor system (and with the advent of hyperthreading, this is becoming more and more prevalent), where there are two runnable threads, one with higher priority than the other. The scheduler will first assign the high-priority thread to one of the processors. But it still has a spare CPU to burn, so the low-priority thread will be assigned to the second CPU. You now have a lower priority thread running simultaneously as a higher priority thread.

    Of course, another way a lower priority thread can run even though there are higher priority threads in the system is simply that all the higher priority threads are blocked. In addition to the cases you might expect, namely waiting on a synchronization object such as a semaphore or a critical section, a thread can also block for I/O or for paging. Paging is the wildcard here, since you don't have any control over when the system might decide to page out the memory you were using due to memory pressure elsewhere in the system.

    The moral of the story is that thread priorities are not a substitute for proper synchronization.

    Next time, a reversal of this fallacy.

  • The Old New Thing

    The things in the PDC 2005 introductory video

    • 29 Comments

    I remarked earlier that the creative director for the PDC rummaged through our offices looking for stuff which was to be used in the opening PDC video to decorate a developer's cubicle. It all flashed by really quickly, but if you were paying attention, you might have been able to make out the following:

    One thing you won't find in the developer's cubicle, however, is a can of soda. That's because none of the soda companies would give permission for their product to appear in this video.

    Later in the video, several pages from the web site tastingmenu.com are flashed across the screen. Puzzle: Why was this site chosen?

    (For legal reasons, I can't provide a link to the video. Any comments that claim to include a link to the video will be deleted, sorry.)

  • The Old New Thing

    New device detected: Boeing 747

    • 29 Comments

    Once again, airplane manufacturers have been giving serious consideration to offering Internet access in the skies. Back in 1994, Boeing considered equipping each seat with a serial modem. Laptop users could hook up to the modem and dial out. (Dial-up was the primary means of connecting to the Internet back in those days.)

    We chuckled at the though of attaching the serial cable and getting a Plug-and-Play pop-up message:

    New device detected: Boeing 747
  • The Old New Thing

    One person's discoverable feature is another person's annoyance

    • 28 Comments

    When I discussed the behavior of Windows XP SP2's autoplay dialog, one person suggested making the CD autoplay configuration dialog more discoverable to solve the problem of people not knowing how to get back to the dialog to change the settings later.

    But what is the boundary between discoverability and annoying behavior?

    Windows 95 drew a bouncy arrow pointing to the Start button to draw your attention to it, because usability testing revealed that it wasn't discoverable enough. Yet there existed a population of people who found the arrow downright annoying. And this even though it only appeared once; the moment you clicked on the Start button, the arrow went away forever. But for those people, apparently, even once is annoying.

    The autoplay configuration dialog is in a somewhat intuitive place: It's a property on the CD drive itself. Though apparently it's not intuitive enough for some. Even the ultra-geeky Tweak UI PowerToy tells you this. Then again, maybe ultra-geeks are too cool to use Tweak UI.

    The fact that many people don't realize where the autoplay configuration settings are kept could mean one of several things. First, it might mean that the location is still not discoverable enough. But configurating one's autoplay settings is hardly a common activity. Do you really want a balloon to pop up each time a CD autoplays saying "Click here to change your autoplay settings"? What if your default autoplay action was "do nothing"? Do you want a balloon to pop up saying "See, I'm not doing anything, just like you told me"? Moreover, if the CD you inserted launches a fullscreen game, the balloon won't be visible anyway, rendering the entire exercise moot.

    Another possible reason why people don't find the CD autoplay configuration dialog is that it doesn't even occur to them that this is a configurable behavior; they simply don't even realize that the dialog exists. If you don't know that something exists, you certainly won't go looking for it. (This is why it is often said that a significant part of the scientific research process is merely asking the right question.)

    Identifying this boundary and knowing when you've crossed is a hard thing to figure out. If you ask ten people, you will get ten different answers. The ability to strike a balance is one of those things you just develop a sense of from experience, supported by years of usability research.

Page 1 of 5 (41 items) 12345