应用程序图标设置 系统图标缓存问题

应用程序图标设置 系统图标缓存问题

在给应用程序EXE更新图标时,遇到一个很奇怪的问题。设置后,图标还是旧图标,最开始以为设置失败,最后发现换个目录下,图标正确了。
很奇怪,查了许久,网上还啥脚本呀,电脑重启下呀,一大推。。。。后来才知道原来系统有个图标的缓存。不知道是不是缓存出问题了。反正东搞搞西搞搞,设置后成功了,图标也重新刷新了,
代码如下

代码

//代码来源于网络,但是我反正未设置成功,以下是经过我修改后的最终代码
void setApplicationIcon(const QString &application, const QString &icon)
{
	LPICONDIRENTRY pIconDirEntry(NULL);
	LPGRPICONDIR pGrpIconDir(NULL);
	HEADER header;
	LPBYTE pIconBytes(NULL);
	HANDLE hIconFile(NULL);
	DWORD dwRet(0), nSize(0), nGSize(0), dwReserved(0);
	HANDLE hUpdate(NULL);
	BOOL ret(FALSE);
	WORD i(0);

	//打开图标文件
	hIconFile = CreateFile((wchar_t*)QDir::toNativeSeparators(icon).utf16(), GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hIconFile == INVALID_HANDLE_VALUE)
	{
		return;
	}
	//读取文件头部信息
	ret = ReadFile(hIconFile, &header, sizeof(HEADER), &dwReserved, NULL);
	if (!ret)
	{
		CloseHandle(hIconFile);
		return;
	}
	//建立每一个图标的目录信息存放区域
	pIconDirEntry = (LPICONDIRENTRY)new BYTE[header.idCount*sizeof(ICONDIRENTRY)];
	if (pIconDirEntry == NULL)
	{
		CloseHandle(hIconFile);
		return;
	}
	//从Icon文件中读取每一个图标的目录信息
	ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);
	if (!ret)
	{
		delete[] pIconDirEntry;
		CloseHandle(hIconFile);
		return;
	}
	//建立EXE文件中RT_GROUP_ICON所需的数据结构存放区域
	nGSize = sizeof(GRPICONDIR) + header.idCount*sizeof(ICONDIRENTRY);
	pGrpIconDir = (LPGRPICONDIR)new BYTE[nGSize];
	//填充信息,这里相当于一个转换的过程
	pGrpIconDir->idReserved = header.idReserved;
	pGrpIconDir->idType = header.idType;
	pGrpIconDir->idCount = header.idCount;
	//复制信息并设置每一个图标对应的ID。ID为位置索引号
	for (i = 0; i < header.idCount; i++)
	{
		pGrpIconDir->idEntries[i].bWidth = pIconDirEntry[i].bWidth;
		pGrpIconDir->idEntries[i].bHeight = pIconDirEntry[i].bHeight;
		pGrpIconDir->idEntries[i].bColorCount = pIconDirEntry[i].bColorCount;
		pGrpIconDir->idEntries[i].bReserved = pIconDirEntry[i].bReserved;
		pGrpIconDir->idEntries[i].wPlanes = pIconDirEntry[i].wPlanes;
		pGrpIconDir->idEntries[i].wBitCount = pIconDirEntry[i].wBitCount;
		pGrpIconDir->idEntries[i].dwBytesInRes = pIconDirEntry[i].dwBytesInRes;
		pGrpIconDir->idEntries[i].nID = i + 1;
	}
	//开始更新EXE中的图标资源,ID定为最小0,如果原来存在0ID的图标信息则被替换为新的。
	hUpdate = BeginUpdateResourceW((wchar_t*)QDir::toNativeSeparators(application).utf16(), false);
	if (hUpdate != NULL)
	{
		//首先更新RT_GROUP_ICON信息
		ret = UpdateResourceW(hUpdate, RT_GROUP_ICON, L"IDI_ICON1", MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pGrpIconDir, nGSize);
		if (!ret)
		{
			delete[] pIconDirEntry;
			delete[] pGrpIconDir;
			CloseHandle(hIconFile);
			return;
		}
		//接着的是每一个Icon的信息存放
		for (i = 0; i < header.idCount; i++)
		{
			//Icon的字节数
			nSize = pIconDirEntry[i].dwBytesInRes;
			//偏移文件的指针到当前图标的开始处
			dwRet = SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);
			if (dwRet == INVALID_SET_FILE_POINTER)
			{
				qDebug() << "error = " << ::GetLastError();
				break;
			}
			//准备pIconBytes来存放文件里的Byte信息用于更新到EXE中。
			delete[] pIconBytes;
			pIconBytes = new BYTE[nSize];
			ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);
			if (!ret)
			{
				qDebug() << "error = " << ::GetLastError();
				break;
			}
			//更新每一个ID对应的RT_ICON信息
			ret = UpdateResourceW(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPVOID)pIconBytes, nSize);
			if (!ret)
			{
				qDebug() << "error = " << ::GetLastError();
				break;
			}
			qDebug() << "UpdateResourceW Success!";
		}
		//结束EXE资源的更新操作
		if (pIconBytes != NULL)
		{
			delete[] pIconBytes;
		}
		EndUpdateResourceW(hUpdate, false);
	}
	//清理资源并关闭Icon文件,到此更新操作结束!
	delete[] pGrpIconDir;
	delete[] pIconDirEntry;
	CloseHandle(hIconFile);
}

以上只是设置了应用程序图标,下面代码则是刷新缓存图标,让EXE显示最新图标

#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <shlobj.h>
#endif

PIDLIST_ABSOLUTE pidl;
	if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_COMMON_APPDATA, 0, 0, &pidl))) {
		SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, pidl, 0);
		CoTaskMemFree(pidl);
	}

执行文件

Qt交流大会 853086607 (1元群,用于后期升级群费用)
在这里插入图片描述

结尾

不定期上传新作品,解答群中作品相关问题。相关外,能解答则解答。欢迎大家一起探索Qt世界!

发布了102 篇原创文章 · 获赞 165 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/ly305750665/article/details/89194135