Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change and refresh icons programmatically (without rebooting)

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!

like image 887
user966939 Avatar asked Oct 07 '22 02:10

user966939


2 Answers

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.

like image 153
user966939 Avatar answered Oct 10 '22 02:10

user966939


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

like image 25
SeanC Avatar answered Oct 10 '22 02:10

SeanC