如何刷新explorer.exe图标缓存
2022-05-23 / Hell
在做客户端定制化时,遇到了问题。客户在新版本时,更换了应用程序图标。在安装新版本的应用后,桌面上的快捷方式还是老版本。
这是因为explorer.exe有缓存,一般情况下,重启explorer.exe即可更新图标。但是偶现几例顽固现场,重启也不生效。
通过搜索,发现翻来覆去都是几个固定的方法:
- 删除IconCache.db
- 删除
%LOCALAPPDATA%\Microsoft\Windows\Explorer
路径下的iconcache - 使用
ie4uinit.exe
但是经过测试发现效果并不好。经过测试,发现系统的1
2ie4uinit.exe -ClearIconCache
ie4uinit.exe -show磁盘清理
工具有效果。
![磁盘清理工具](disk clean.png)
那么问题就变得简单起来,如何安装程序执行后,进行一次磁盘清理操作呢?
磁盘清理工具C:\WINDOWS\system32\cleanmgr.exe提供了一些参数:但是没有一个符合我的需要,我只是需要调用一下以清除缩略图,但是并没有可以实现的方式。1
cleanmgr [/d <driveletter>] [/sageset:n] [/sagerun:n] [/TUNEUP:n] [/LOWDISK] [/VERYLOWDISK]
但是看到一篇文章:Creating a Disk Cleanup Handler,既然我们可以创建磁盘清理项,那其自带的应该也是类似方式提供的。
在文章末尾Example Registration of a Disk Cleanup Handler,发现了注册表路径:,可以看到,它的GUID是{889900c3-59f3-4c2f-ae21-a409ea01e605}
,我们根据接口,尝试一波调用,就成功了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class VolumeCacheCallback : public IEmptyVolumeCacheCallBack
{
public:
// 通过 IEmptyVolumeCacheCallBack 继承
virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override
{
return E_NOTIMPL;
}
virtual ULONG __stdcall AddRef(void) override
{
return 0;
}
virtual ULONG __stdcall Release(void) override
{
return 0;
}
virtual HRESULT __stdcall ScanProgress(DWORDLONG dwlSpaceUsed, DWORD dwFlags, LPCWSTR pcwszStatus) override
{
printf_s("Scanning files %llu\n", dwlSpaceUsed);
return S_OK;
}
virtual HRESULT __stdcall PurgeProgress(DWORDLONG dwlSpaceFreed, DWORDLONG dwlSpaceToFree, DWORD dwFlags, LPCWSTR pcwszStatus) override
{
printf_s("Cleanning files %llu\n", dwlSpaceFreed);
return S_OK;
}
};
bool cleaner()
{
HRESULT hr = E_FAIL;
IEmptyVolumeCache2* pCache2 = nullptr;
bool bComInit = false;
bool bRet = false;
do
{
hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (S_OK != hr && S_FALSE != hr) {
if (RPC_E_CHANGED_MODE != hr) {
break;
}
}
else {
bComInit = true;
}
CLSID clean_Thumbnail_Cache = { 0 };
hr = CLSIDFromString(L"{889900c3-59f3-4c2f-ae21-a409ea01e605}", &clean_Thumbnail_Cache);
if (FAILED(hr))
{
printf_s("CLSIDFromString failed\n");
break;
}
hr = ::CoCreateInstance(clean_Thumbnail_Cache, NULL, CLSCTX_INPROC_SERVER, __uuidof(IEmptyVolumeCache2), (void**)&pNetFwP2);
if (FAILED(hr) || nullptr == pCache2)
{
printf_s("CoCreateInstance Failed : 0x%08X\n", hr);
break;
}
DWORDLONG space_used = 0;
VolumeCacheCallback callback;
hr = pCache2->GetSpaceUsed(&space_used, &callback);
if (FAILED(hr))
{
printf_s("GetSpaceUsed Failed : 0x%08X\n", hr);
break;
}
printf_s("Scanning files Complete\n");
hr = pCache2->Purge(space_used, &callback);
if (FAILED(hr))
{
printf_s("Purge Failed : 0x%08X\n", hr);
break;
}
printf_s("Cleanning files Complete\n");
bRet = true;
} while (false);
if (nullptr != pCache2) {
pCache2->Release();
}
if (bComInit) {
CoUninitialize();
}
return bRet;
}
PermaLink:
https://lazywang.life/2022/05/23/how-to-refresh-explorer-icon-cache/