奇怪的Windows 7桌面图标缓存
我正在编写一个 C# 应用程序来更改桌面上的默认回收站图标。我通过将图标传输到驱动器上的特定位置并更新注册表以指向新图标来实现此目的。这非常有效。
但是,问题是当我卸载应用程序并想要将图标设置为默认值时。当我在 Windows 中使用内置函数进行测试时,我注意到 Windows 有时会将空图标和 %SystemRoot%\System32 的注册表更改为
表示完整图标,有时 %SystemRoot%\System32\imageres.dll,50
\imageres.dll,49%SystemRoot%\System32\imageres.dll,-55
表示空图标,%SystemRoot%\System32\imageres.dll ,-54
表示完整图标。我似乎确实找不到有时使用 50 和 49,有时使用 -55 -54 作为默认回收站图标的逻辑,也找不到有关此问题的任何信息。
我还尝试删除 User\username\AppData\Local 中的图标缓存,但没有任何效果。问题是当我设置默认图标(例如使用 50 和 49)时,它不会自动更新。我每次都必须手动刷新才能更改其状态(空/满)。如果我后来转到 Windows 中的内置功能并设置默认图标,如果我使用 50 和 49,它会更改为 -55 或 -54,然后它就可以工作了。卧槽?注册表中一定有其他地方触发了这个..你能帮我吗?
我正在处理的注册表中的位置:
HKEY_CURRENT_USER\
Software\
Microsoft\
Windows\
CurrentVersion\
Explorer\
CLSID\
{645FF040-5081-101B-9F08-00AA002F954E}\
DefaultIcon
编辑18/04-2011
在Anders的帖子之后我想出了这个:
[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);
但它不会改变任何东西:(
编辑19/ 02-2011
在安德斯的帖子之后我更新了这个:
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
并尝试了所有这些组合:
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);
仍然不起作用:(
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 :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
-55是资源id,50是资源索引。资源id由开发人员设置,索引是从0开始的计数(计数可能在服务包等中改变,但它们通常相当稳定)。您可以使用 Resource Hacker 等工具查看资源 ID(在图标组中查找图标 id)
当您在图标选择器对话框中选择图标时,通常会使用索引。我希望特定的 Windows 重置按钮使用资源 id...
请参阅 这个回答 强制刷新 shell 图标的方法
-55 is a resource id, 50 is a resource index. The resource id is set by the developer, the index is a count starting from 0 (The count could change in a service pack etc, but they are usually pretty stable). You can view resource id's with a tool like Resource Hacker (Look in Icon Group for icon id's)
When you pick a icon in the icon picker dialog, the index is normally used. I would expect a specific windows reset button to use the resource id...
See this answer for a way to force a shell icon refresh