Win32 输入exe路径和图标路径,替换exe图标,实现函数
时间: 2023-11-27 15:50:10 浏览: 141
以下是一个实现替换exe图标的函数:
```c++
#include <Windows.h>
#include <string>
BOOL SetExeIcon(LPCWSTR exePath, LPCWSTR iconPath)
{
// 加载图标资源
HICON hIcon = (HICON)LoadImage(NULL, iconPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
if (!hIcon)
return FALSE;
// 打开exe文件
HANDLE hFile = CreateFileW(exePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DestroyIcon(hIcon);
return FALSE;
}
// 获取exe文件的文件头
IMAGE_DOS_HEADER dosHeader;
DWORD bytesRead;
if (!ReadFile(hFile, &dosHeader, sizeof(dosHeader), &bytesRead, NULL) || bytesRead != sizeof(dosHeader) || dosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取PE文件头
IMAGE_NT_HEADERS ntHeader;
if (!SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN) ||
!ReadFile(hFile, &ntHeader, sizeof(ntHeader), &bytesRead, NULL) || bytesRead != sizeof(ntHeader) || ntHeader.Signature != IMAGE_NT_SIGNATURE)
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取资源目录表
IMAGE_DATA_DIRECTORY resourceDir = ntHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if (resourceDir.VirtualAddress == 0 || resourceDir.Size == 0)
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取资源目录表的位置
DWORD resourceDirOffset = resourceDir.VirtualAddress + dosHeader.e_lfanew;
if (!SetFilePointer(hFile, resourceDirOffset, NULL, FILE_BEGIN))
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取资源目录表
IMAGE_RESOURCE_DIRECTORY resDir;
if (!ReadFile(hFile, &resDir, sizeof(resDir), &bytesRead, NULL) || bytesRead != sizeof(resDir))
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取资源目录项
IMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry;
if (!ReadFile(hFile, &resDirEntry, sizeof(resDirEntry), &bytesRead, NULL) || bytesRead != sizeof(resDirEntry))
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 找到图标资源的位置
DWORD iconResOffset = resDirEntry.OffsetToData & 0x7FFFFFFF;
if (!SetFilePointer(hFile, resourceDirOffset + iconResOffset, NULL, FILE_BEGIN))
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 获取图标资源头
IMAGE_RESOURCE_DATA_ENTRY iconDataEntry;
if (!ReadFile(hFile, &iconDataEntry, sizeof(iconDataEntry), &bytesRead, NULL) || bytesRead != sizeof(iconDataEntry))
{
CloseHandle(hFile);
DestroyIcon(hIcon);
return FALSE;
}
// 读取图标数据
BYTE* iconData = new BYTE[iconDataEntry.Size];
if (!ReadFile(hFile, iconData, iconDataEntry.Size, &bytesRead, NULL) || bytesRead != iconDataEntry.Size)
{
CloseHandle(hFile);
DestroyIcon(hIcon);
delete[] iconData;
return FALSE;
}
// 替换图标数据
ICONHEADER* iconHeader = (ICONHEADER*)iconData;
iconHeader->idReserved = 0;
iconHeader->idType = 1;
iconHeader->idCount = 1;
ICONDIRENTRY* iconDirEntry = (ICONDIRENTRY*)(iconData + sizeof(ICONHEADER));
iconDirEntry->bWidth = GetSystemMetrics(SM_CXICON);
iconDirEntry->bHeight = GetSystemMetrics(SM_CYICON);
iconDirEntry->bColorCount = 0;
iconDirEntry->bReserved = 0;
iconDirEntry->wPlanes = 1;
iconDirEntry->wBitCount = 32;
iconDirEntry->dwBytesInRes = iconDataEntry.Size - sizeof(ICONHEADER) - sizeof(ICONDIRENTRY);
iconDirEntry->dwImageOffset = sizeof(ICONHEADER) + sizeof(ICONDIRENTRY);
BYTE* iconImage = iconData + iconDirEntry->dwImageOffset;
BITMAPINFOHEADER* biHeader = (BITMAPINFOHEADER*)iconImage;
biHeader->biSize = sizeof(BITMAPINFOHEADER);
biHeader->biWidth = GetSystemMetrics(SM_CXICON);
biHeader->biHeight = GetSystemMetrics(SM_CYICON) * 2;
biHeader->biPlanes = 1;
biHeader->biBitCount = 32;
biHeader->biCompression = BI_RGB;
biHeader->biSizeImage = iconDirEntry->dwBytesInRes;
BYTE* iconBits = iconImage + sizeof(BITMAPINFOHEADER);
GetIconInfo(hIcon, NULL, (BITMAPINFO*)biHeader, (void**)&iconBits);
DestroyIcon(hIcon);
// 写入替换后的图标数据
iconDataEntry.Size = iconDataEntry.Size;
if (!SetFilePointer(hFile, -(LONG)bytesRead, NULL, FILE_CURRENT) || !WriteFile(hFile, iconData, iconDataEntry.Size, &bytesRead, NULL))
{
CloseHandle(hFile);
delete[] iconData;
return FALSE;
}
// 清理资源
delete[] iconData;
CloseHandle(hFile);
return TRUE;
}
```
使用方法如下:
```c++
std::wstring exePath = L"path/to/exe.exe";
std::wstring iconPath = L"path/to/icon.ico";
if (SetExeIcon(exePath.c_str(), iconPath.c_str()))
{
// 替换成功
}
else
{
// 替换失败
}
```
阅读全文