I'm writing a C# app that changes the default recycle bin icon on the desktop. I'm doing this by transferring the icons to a specific place on the drive and updating the registry to point to the new icons. This works quite well.
However, the problem is when I'm uninstalling the app and want to set back the icons as default. When I test with the built in function in Windows, I notice that Windows sometimes changes the registry to %SystemRoot%\System32\imageres.dll,50
for empty icon and %SystemRoot%\System32\imageres.dll,49
for full icon AND sometimes %SystemRoot%\System32\imageres.dll,-55
for empty icon and %SystemRoot%\System32\imageres.dll,-54
for full icon. I really can't seem to find the logic in sometimes using 50 and 49 and sometimes -55 -54 for the default recycle bin icon nor can I find any information regarding this issue.
I've also tried deleting the icon cache in User\username\AppData\Local without any effect. The problem is when I'm setting back the default icons (with using for example 50 and 49) it wont update automatically. I have to manually refresh every time in order to change its state (empty/full). If I afterwards go to the built in function in Windows and set back default icons it changes to -55 or -54 if I used 50 and 49 and it then works. Wtf? There must be somewhere else in the registry which triggers this.. can you help me?
The place in registry I'm working with:
HKEY_CURRENT_USER\
Software\
Microsoft\
Windows\
CurrentVersion\
Explorer\
CLSID\
{645FF040-5081-101B-9F08-00AA002F954E}\
DefaultIcon
Edit 18/04-2011
After Anders' post i've come up with this:
[System.Runtime.InteropServices.DllImport("User32.dll")]
public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
[System.Runtime.InteropServices.DllImport("User32.dll")]
public static extern long SendMessageTimeout(int hWnd, int Msg, int wParam, int lParam, int fuFlags, int uTimeout, out int lpdwResult);
private const int SPI_SETICONS = 0x0058;
private const int SPIF_UPDATEINIFILE = 0x1;
private const int SPIF_SENDWININICHANGE = 0x2;
private const int HWND_BROADCAST = 0xffff;
private const int WM_SETTINGCHANGE = 0x001A;
private const int SMTO_ABORTIFHUNG = 0x0002;
private const int SPI_SETNONCLIENTMETRICS = 0x0002;
int res = 0;
RegistryKey iconSizeKey = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop\\WindowMetrics", true);
int iconSize = Int16.Parse((string)iconSizeKey.GetValue("Shell Icon Size"));
int newIconSize = iconSize - 1;
iconSizeKey.SetValue("Shell Icon Size", newIconSize, RegistryValueKind.String);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 100000, out res);
iconSizeKey.SetValue("Shell Icon Size", iconSize, RegistryValueKind.String);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 100000, out res);
But it doesn't change anything :(
Edit 19/02-2011
After Anders' post I've updated this:
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
And tried all these combinations:
SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
SHChangeNotify(0x08000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
SHChangeNotify(0x00008000, 0x1000, IntPtr.Zero, IntPtr.Zero);
SHChangeNotify(0x00002000, 0x1000, IntPtr.Zero, IntPtr.Zero);
Still doesn't work :(