问题
When I'm replacing icons manually (i.e. NOT from the Folder Options window in explorer), the icon(s) aren't being updated. For example, if I execute this batch code:
REG ADD HKCR\testfile\DefaultIcon /ve /d "C:\test.ico,0" /f
the icon(s) show like they should in the list in Folder Options, but the icons aren't updated on the desktop or in explorer.
The icons are updated if I just hit the "change icon" button for any file type and exit the Folder Options window. But this can't be done via batch or VBS as far as I know.
Restarting explorer.exe DOES work, but if I do that, the application tabs in the task bar become buggy for some reason (e.g.: when an application is maximized, I can't just left click the tab in the task bar to minimize it anymore - I have to actually right click it and hit minimize...). Not to mention, if I do it that way, all open explorer windows will close down, and that's a little bothersome.
I also have a copy of TuneUp Utilities, which has an option for reloading the icon cache, and this does work like intended. But once again, I can't access this tool via batch or VBS. And it doesn't restart explorer.exe or remove any files (like some solutions do). I'm positive of this since I don't have iconcache.db files anywhere on my OS drive.
I also tried adding the registry entries via VBS instead, but that didn't help.
Any batch or VBScript solutions are welcome!
回答1:
By associating files, the system refreshes the icons, so my simple solution was just this:
ASSOC .anyextension=anytype
ASSOC .anyextension=
Second row disassociates the extension.
回答2:
This page has a VB program that rebuilds the cache (look at frmRebuiltIconCache.frm for the actual code)
What it does is to examine the value of HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size
, subtract 1 from it, forces a timeout via SendMessageTimeout
, then resets the value, and repeats the timeout
due to the fact you cannot call a DLL from vbs (without an external program), this may not give you what you need. I have pared down the program to this:
'SendMessageTimeout values
Const HWND_BROADCAST = &HFFFF
Const WM_SETTINGCHANGE = &H1A
Const SPI_SETNONCLIENTMETRICS = &H2A
Const SMTO_ABORTIFHUNG = &H2
'Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" _
' (ByVal hwnd As Long, ByVal msg As Long, _
' ByVal wParam As Long, ByVal lParam As Long, _
' ByVal fuFlags As Long, ByVal uTimeout As Long, _
' lpdwResult As Long) As Long
Dim icon_size
Dim new_icon_size
Dim result
Dim SysVarReg
Set SysVarReg = WScript.CreateObject("WScript.Shell")
' Get the current icon size.
icon_size = SysVarReg.RegRead ("HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size")
' Increase the value by 1.
new_icon_size = CInt(icon_size) + 1
SysVarReg.RegWrite "HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size", new_icon_size
' Send HWND_BROADCAST to refresh the icons.
SendMessageTimeout HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 10000, result
' Restore the original value.
SysVarReg.RegWrite "HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size", icon_size
' Send HWND_BROADCAST to refresh the icons again.
SendMessageTimeout HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 10000, result
but without something to wrap the DLL call in, you will be unable to do this via vbs
回答3:
' It work in XP.
' The following is "VBA" Module.
' ---------------------------------------------------------
'SendMessageTimeout values
Const HWND_BROADCAST = &HFFFF
Const WM_SETTINGCHANGE = &H1A
Const SPI_SETNONCLIENTMETRICS = &H2A
Const SMTO_ABORTIFHUNG = &H2
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" _
(ByVal hwnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long, _
ByVal fuFlags As Long, ByVal uTimeout As Long, _
lpdwResult As Long) As Long
Sub Rebuild_Icon_cache()
Dim icon_size
Dim new_icon_size
Dim result
Dim SysVarReg
Set SysVarReg = CreateObject("WScript.Shell")
' Get the current icon size.
icon_size = SysVarReg.RegRead("HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size")
' Increase the value by 1.
new_icon_size = CInt(icon_size) + 1
SysVarReg.RegWrite "HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size", new_icon_size
' Send HWND_BROADCAST to refresh the icons.
SendMessageTimeout HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 10000, result
' Restore the original value.
SysVarReg.RegWrite "HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size", icon_size
' Send HWND_BROADCAST to refresh the icons again.
SendMessageTimeout HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0, SMTO_ABORTIFHUNG, 10000, result
End Sub
来源:https://stackoverflow.com/questions/13263577/change-and-refresh-icons-programmatically-without-rebooting