以编程方式更改和刷新图标(无需重新启动)
Posted
技术标签:
【中文标题】以编程方式更改和刷新图标(无需重新启动)【英文标题】:Change and refresh icons programmatically (without rebooting) 【发布时间】:2012-10-27 03:30:51 【问题描述】:当我手动替换图标时(即不是从资源管理器中的文件夹选项窗口),图标不会被更新。例如,如果我执行这个批处理代码:
REG ADD HKCR\testfile\DefaultIcon /ve /d "C:\test.ico,0" /f
图标在“文件夹选项”的列表中显示为应有的样子,但图标未在桌面或资源管理器中更新。
如果我只是点击任何文件类型的“更改图标”按钮并退出“文件夹选项”窗口,图标就会更新。但据我所知,这不能通过批处理或 VBS 来完成。
重新启动 explorer.exe 确实有效,但如果我这样做,任务栏中的应用程序选项卡会由于某种原因出现错误(例如:当应用程序最大化时,我不能只左键单击任务栏中的选项卡再最小化它 - 我实际上必须右键单击它并点击最小化......)。更何况,如果我这样做,所有打开的资源管理器窗口都会关闭,这有点麻烦。
我还有一份 TuneUp Utilities 的副本,它有一个重新加载图标缓存的选项,这确实像预期的那样工作。但再一次,我无法通过批处理或 VBS 访问此工具。它不会重新启动 explorer.exe 或删除任何文件(就像某些解决方案一样)。我对此持肯定态度,因为我的操作系统驱动器上任何地方都没有 iconcache.db 文件。
我也尝试通过 VBS 添加注册表项,但没有帮助。
欢迎任何批处理或 VBScript 解决方案!
【问题讨论】:
【参考方案1】:通过关联文件,系统会刷新图标,所以我的简单解决方案是这样的:
ASSOC .anyextension=anytype
ASSOC .anyextension=
第二行取消与扩展的关联。
【讨论】:
【参考方案2】:This page 有一个重建缓存的 VB 程序(查看 frmRebuiltIconCache.frm 以获取实际代码)
它的作用是检查HKCU\Control Panel\Desktop\WindowMetrics\Shell Icon Size
的值,从中减去1,通过SendMessageTimeout
强制超时,然后重置该值,并重复超时
由于您无法从 vbs(没有外部程序)调用 DLL,这可能无法满足您的需求。我已将程序缩减为:
'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
但如果没有东西来包装 DLL 调用,您将无法通过 vbs 执行此操作
【讨论】:
这不是 VB脚本 解决方案。也没有办法将其移植到 VBS,是吗?我之所以需要它是批处理或VBS,是因为这应该在重新安装操作系统后直接执行。所以我不应该先安装其他程序。不过谢谢! 我在尝试时收到此错误:语法错误,第 1 行,字符 9,代码 800A03EA。我不知道它在其他 Windows 系统上是否有任何不同,但至少在 XP 中它对我不起作用......【参考方案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
【讨论】:
您能否添加一些额外的信息以及您的答案? 马虎。dim result
?错误:附加信息:对 PInvoke 函数 'WHOSeBox!WHOSeBox.MainBoot::SendMessageTimeout' 的调用使堆栈不平衡。以上是关于以编程方式更改和刷新图标(无需重新启动)的主要内容,如果未能解决你的问题,请参考以下文章
如何在不重新启动 Web 应用程序的情况下以编程方式使 JavaScript 和 CSS 包无效或刷新?