How do I preserve the user’s notification icon preferences for my program after I update it?

When a program creates a notification icon, the user can set preferences for that icon: Show icon and notifications, Hide icon and notifications, and Only show notifications. When you update the program, what do you have to do to get those preferences to carry over to the new program?

Give your notification icon a GUID.

Specifically, in the NOTIFY­ICON­DATA structure, set the NIF_GUID flag in the uFlags and put a GUID in the guidItem member. If the old version of the program and the updated version use the same GUID, then the system will recognize that the new icon should pick up the settings from the old icon.

More generally, the GUID is how the system decides which user preferences apply to which icons. When the user selects preferences for an icon, the system associates those preferences with the GUID, and the next time an icon with the same GUID appears, the system uses those preferences.

But what happens if you don't specify a GUID?

In that case, the system starts applying heuristics. It checks whether the full path to the executable is mostly the same, where "mostly the same" means that some directories are considered equivalent; for example, a file in Program Files is considered to match a corresponding file in Program Files (x86). If the executable is mostly the same, then the system applies additional fuzzy logic based on trying to match some combination of the uID, the tooltip provided in the szTip member, and the pixels in the icon provided in the hIcon.¹ If the fuzzy matcher says "Yeah, they're probably the same," then the system will consider the two icons as equivalent and share their settings.

Note that this heuristic is a fallback, so you shouldn't rely on it in your programs. You should just set a GUID on your notification icon so that you get consistent behavior.

Bonus chatter: If you generate notification icons dynamically, you would want to specify a GUID that is deterministically generated from whatever identity you use to generate your notification icon. For example, if you create a separate notification icon for each server that you discover, then you can hash the server name in order to produce a type 3 or type 5 UUID. That way, when you encounter the same server in the future, you will regenerate the same GUID.

¹ Note that this means that programs that animate their icon are less likely to have a successful match because the pixels of the icon that the preferences were saved under may not match the pixels of the icon that is currently being displayed.

Comments (11)
  1. henke37 says:

    This reminds me of the taskbar button grouping and pinning using AppIDs.

  2. stan423321 says:

    So does that mean I can work around the fuzzy logic and reset user settings by regenerating GUIDs?

  3. Joshua says:

    Hey maybe I can finally rewrite my “show me my IP address in the notification area” program and make it usable again.

  4. Scarlet Manuka says:

    Cue someone, somewhere, misapplying (or only remembering half of) this advice, and generating a new GUID for each version of their program, thus ensuring that the settings will never carry across. (I suppose this could even be a “nice bonus for that” feature, if your program is so awesome that you want to make sure users have the opportunity to see your notifications every time it’s updated.)

    1. Simon Clarkstone says:

      Why wait for it to be updated? You could change the GUID every day and every startup.

    2. Tanveer Badar says:

      Even worse. Someone relying on the heuristics shared above without understanding they might be an implementation detail and subject to change at any time. Now that rules are written here, they are part of official contract for shell. Aren’t they? :P

      1. ErikF says:

        Even better, have your program find the GUID of a competitor’s program’s (or a Windows component’s) icon and use that. This way, the user can’t turn off your icon without interfering with the other one! Nothing says ingenuity like thinking outside the box.

  5. Kipters says:

    This might be a problem in .NET land since the NotifyIcon from Windows Forms (also used in WPF apps) doesn’t use GUIDs

    1. Joshua Schaeffer says:

      Most of the .NET Framework is easy to rewrite better than the original. The problem I worry about is somebody using a random GUID every time and clogging up all the automatically saved settings.

  6. DWalker07 says:

    But we might run out of GUIDs! :-)

  7. Doug says:

    what’s preventing someone from stealing a well known program’s GUID to get himself a whitelisted icon?

Comments are closed.

Skip to main content