NOTIFYICONDATA - GUID problem
According to the description for the guidItem member of the NOTIFYICONDATA structure at http://msdn.microsoft.com/en-us/library/bb773352(v=vs.85).aspx programs that make use of the Windows system tray need to identify their icon with a valid GUID on Windows 7. I did this, but I'm running into a problem. If my application is running in directory A and then the user at some point decides to move it and run it in directory B, when the program makes the call to Shell_NotifyIcon it fails (returns 0) with GetLastError set to 1460 (ERROR_TIMEOUT).
If you read further down at the very bottom of that MSDN article to troubleshooting point 2, it basically describes that programs identifying their system tray icon with a GUID cannot change paths or this will happen. It also then has this interesting little blurb in it:
If the path must be changed, the application should remove any GUID information that was added when the existing icon was registered.
Does anyone know of a Win32 API call or a way to do this? Presuma开发者_StackOverflow中文版bly this would be a function taking the GUID that I want to remove, and calling it would remove any settings for any exe that windows identified as using this GUID. If so, I could setup my program to attempt to call Shell_NotifyIcon, and then if it fails, I'll call a function to clear everything out and try again.
The only other option I can think of to allow a program that has the potential for needing to be run in multiple locations (not at the same time) to use the same GUID for its system tray icon is to brute force modify the settings in the registry according to this article: http://deployment.xtremeconsulting.com/2011/07/08/windows-7-notification-area-automation-falling-back-down-the-binary-registry-rabbit-hole/ I would like to avoid this approach if possible, for obvious reasons.
Any help on this issue will be greatly appreciated.
Here's a complete list of possibilities that I'm aware of:
- sign your EXE with a valid certificate;
- do not ever move the EXE (precludes portable programs);
- do not assign a GUID to your notify icon,
- the hacky approach you linked to,
- generate a GUID based on your application path.
Let's take a look at that last idea, in particular. Windows wants a unique GUID for every path. We just want a GUID that doesn't change for as long as the path is fixed. That's actually trivial to achieve. Here's an outline:
- generate a random GUID using a service like make a guid
- obtain your executable path
- hash your path with a hash function that outputs at least 128 bits, like MD5 or SHA-1
- XOR your GUID with the path hash, truncating to 128 bits
- use the result as the tray icon GUID
This comes with a gotcha: the application path is not necessarily unique. But this shouldn't be a major problem because firstly, most of the time it's unique, and secondly, the worst that will happen if run via an alternative path is that the user will have to reposition the tray icon once.
精彩评论