Win32 输入exe路径和exe资源id和图标路径,替换exe图标,实现函数
时间: 2023-11-27 19:50:16 浏览: 166
以下是一个实现这个功能的示例函数:
```c++
#include <Windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
BOOL ReplaceExeIcon(LPCTSTR lpExePath, DWORD dwIconResourceId, LPCTSTR lpNewIconPath)
{
// 读取exe文件的文件头信息
HANDLE hFile = CreateFile(lpExePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
IMAGE_DOS_HEADER dosHeader;
DWORD dwBytesRead;
if (!ReadFile(hFile, &dosHeader, sizeof(dosHeader), &dwBytesRead, NULL) || dwBytesRead != sizeof(dosHeader))
{
CloseHandle(hFile);
return FALSE;
}
SetFilePointer(hFile, dosHeader.e_lfanew + sizeof(DWORD), NULL, FILE_BEGIN);
IMAGE_FILE_HEADER fileHeader;
if (!ReadFile(hFile, &fileHeader, sizeof(fileHeader), &dwBytesRead, NULL) || dwBytesRead != sizeof(fileHeader))
{
CloseHandle(hFile);
return FALSE;
}
// 根据exe文件头信息找到资源表位置
DWORD dwResourceOffset = dosHeader.e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + fileHeader.SizeOfOptionalHeader;
SetFilePointer(hFile, dwResourceOffset, NULL, FILE_BEGIN);
IMAGE_RESOURCE_DIRECTORY resourceDirectory;
if (!ReadFile(hFile, &resourceDirectory, sizeof(resourceDirectory), &dwBytesRead, NULL) || dwBytesRead != sizeof(resourceDirectory))
{
CloseHandle(hFile);
return FALSE;
}
// 遍历资源表,找到指定的图标资源
IMAGE_RESOURCE_DIRECTORY_ENTRY* pEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((BYTE*)&resourceDirectory + sizeof(resourceDirectory));
for (WORD i = 0; i < resourceDirectory.NumberOfNamedEntries + resourceDirectory.NumberOfIdEntries; i++, pEntry++)
{
if (pEntry->u1.s1.Id == (WORD)RT_GROUP_ICON)
{
// 找到了图标资源组,进入下一层资源表
DWORD dwNextOffset = dwResourceOffset + pEntry->u2.s2.OffsetToDirectory;
SetFilePointer(hFile, dwNextOffset, NULL, FILE_BEGIN);
IMAGE_RESOURCE_DIRECTORY nextResourceDirectory;
if (!ReadFile(hFile, &nextResourceDirectory, sizeof(nextResourceDirectory), &dwBytesRead, NULL) || dwBytesRead != sizeof(nextResourceDirectory))
{
CloseHandle(hFile);
return FALSE;
}
IMAGE_RESOURCE_DIRECTORY_ENTRY* pNextEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((BYTE*)&nextResourceDirectory + sizeof(nextResourceDirectory));
for (WORD j = 0; j < nextResourceDirectory.NumberOfNamedEntries + nextResourceDirectory.NumberOfIdEntries; j++, pNextEntry++)
{
if (pNextEntry->u1.s1.Id == dwIconResourceId)
{
// 找到了指定的图标资源
DWORD dwIconOffset = dwResourceOffset + pNextEntry->u2.s2.OffsetToData;
SetFilePointer(hFile, dwIconOffset, NULL, FILE_BEGIN);
IMAGE_RESOURCE_DATA_ENTRY dataEntry;
if (!ReadFile(hFile, &dataEntry, sizeof(dataEntry), &dwBytesRead, NULL) || dwBytesRead != sizeof(dataEntry))
{
CloseHandle(hFile);
return FALSE;
}
// 读取图标资源
BYTE* pIconData = new BYTE[dataEntry.Size];
if (!ReadFile(hFile, pIconData, dataEntry.Size, &dwBytesRead, NULL) || dwBytesRead != dataEntry.Size)
{
delete[] pIconData;
CloseHandle(hFile);
return FALSE;
}
// 替换图标资源
HANDLE hNewIcon = LoadImage(NULL, lpNewIconPath, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
if (hNewIcon == NULL)
{
delete[] pIconData;
CloseHandle(hFile);
return FALSE;
}
ICONINFO iconInfo;
if (!GetIconInfo((HICON)hNewIcon, &iconInfo))
{
delete[] pIconData;
CloseHandle(hFile);
DestroyIcon((HICON)hNewIcon);
return FALSE;
}
DWORD dwNewIconSize = iconInfo.dwBytesInRes;
BYTE* pNewIconData = new BYTE[dwNewIconSize];
if (!GetIconResourceData(iconInfo.hResInfo, pNewIconData, dwNewIconSize))
{
delete[] pIconData;
delete[] pNewIconData;
CloseHandle(hFile);
DestroyIcon((HICON)hNewIcon);
return FALSE;
}
memcpy(pIconData, pNewIconData, dwNewIconSize);
// 写入替换后的图标资源
SetFilePointer(hFile, dwIconOffset + sizeof(IMAGE_RESOURCE_DATA_ENTRY), NULL, FILE_BEGIN);
if (!WriteFile(hFile, pIconData, dataEntry.Size, &dwBytesRead, NULL) || dwBytesRead != dataEntry.Size)
{
delete[] pIconData;
delete[] pNewIconData;
CloseHandle(hFile);
DestroyIcon((HICON)hNewIcon);
return FALSE;
}
delete[] pIconData;
delete[] pNewIconData;
CloseHandle(hFile);
DestroyIcon((HICON)hNewIcon);
return TRUE;
}
}
}
}
CloseHandle(hFile);
return FALSE;
}
```
调用示例:
```c++
ReplaceExeIcon(TEXT("C:\\MyApp.exe"), 101, TEXT("C:\\NewIcon.ico"));
```
其中,`lpExePath` 参数为需要替换图标的exe文件路径,`dwIconResourceId` 参数为需要替换的图标资源的ID,`lpNewIconPath` 参数为新的图标文件路径。如果函数执行成功,则返回 `TRUE`,如果失败,则返回 `FALSE`。
阅读全文