VC++编程实现修改EXE文件图标
VC++编程实现修改EXE文件图标
方法一:通过API编程实现:
这个问题以前在CSDN上解答过,但是当时只是提了提几个要用到的函数,自己并没有去动手写实现。前几天和某人讨论这个问题,他认为只有通过PE内部的资源偏移才好改,熊猫烧香就是这么搞的,而我坚持API也可以的观点。后来我想了想觉得这个问题值得记住,并自己亲手把它写出来并试验成功。贴出代码来给大家分享:
EnableDebugPrivilge(SE_DEBUG_NAME,TRUE);
HGLOBAL hResLoad(NULL);
HANDLE hExe(NULL);
HRSRC hRes(NULL);
HANDLE hUpdateRes(NULL);
char * lpResLock;
BOOL result;
hExe = LoadLibrary(_TEXT("D:\\Src.exe"));
if (hExe == NULL)
{
AfxMessageBox("加载Src.exe失败.",0,0);
}
hRes = FindResource((HMODULE)hExe, (LPCSTR)1, RT_ICON);
if (hRes == NULL)
{
AfxMessageBox("不能定位Src.exe中的第一个图标");
}
hResLoad = LoadResource((HMODULE)hExe, hRes);
if (hResLoad == NULL)
{
AfxMessageBox("不能加载该图标资源");
}
lpResLock =(char *)LockResource(hResLoad);
if (lpResLock == NULL)
{
AfxMessageBox("不能锁定该资源.");
}
hUpdateRes = BeginUpdateResource("G:\\Target.exe", FALSE);
if (hUpdateRes == NULL)
{
AfxMessageBox("不能打开Target.exe准备写.");
}
result =UpdateResource((HMODULE)hUpdateRes , RT_ICON,
(LPCSTR)1, 0, lpResLock, SizeofResource((HMODULE)hExe, hRes));
if (result == FALSE)
{
AfxMessageBox("添加资源失败.");
}
if (!EndUpdateResource(hUpdateRes, FALSE))
{
AfxMessageBox("不能向目标EXE中写入改动结束资源更新");
}
if (!FreeLibrary((HMODULE)hExe))
{
AfxMessageBox("不能释放Src的句柄.");
}
有人说编程靠思路和套路,这个套路可真是够长的,这么多的函数必须按顺序配套使用,不能有差错。其实按照讨论的VC编程还有很多啊,比如CreateFile、CreateFileMapping、MapViewOfFile、UnmapViewOfFile这也是一个典型套路。
至于EnableDebugPrivilge函数,是提升本进程的权限为DEBUG级别,代码网上有,大家可以自己找找!
方法二:通过PE文件的图标偏移地址实现:
一年前初学VB时我对这个API就特感兴趣,听说这个API可以更改图标资源,就更感兴趣了,后来试了试,发现修改其它资源貌似没多大问题,唯独修改图标时无果,我发现所修改的图虽说已经写入到资源文件中了,但是就是无法显示。后来到网上查了下,发现用UpdateResource修改EXE图标的没一个成功的,大致都是发生成功写入,无法正常显示的问题。罢矣,当时就琢磨着把该问题先放放,等日后有时间再好好折腾。
无奈时间过得太快,忽忽悠悠就过了一年了,前几天,在整理去年的一些源码时发现了这个遗留在硬盘中的代码,一年前无奈自己所学浅溥,啥都不知道,但现在已经对API有了较深厚的认识,再加上对汇编的一些了解,我想此时不解决更待何时。
在折腾这个API的期间也发生不少问题,最让我自责的就是差点被 CreateFile 这个API给Game Over,这个小伟知道(又是小伟?没办法啊,谁要咱和小伟太有缘了~)。还好自己最终醒悟,否则真的要好好鄙视鄙视自己。最初修改时还是和一年前一个样,这时我一直在回想一样年遇到这个问题的问题:所写图标的数据是不是完整的写到了资源文件中?想到此,我用eXeScope(一个PE资源文件查看工具)看了下写入到资源文件中的十六进制,又用UltraEdit-32以十六进制查看ico文件中的数据,发现没问题啊?一字节一字节都对得上,那问题出在哪了?没法,继续在Google游荡,终于找了一份有效的资料(网址现在不知扔哪去了),全E文,看得难受,不过大致的意思是说ICON是由一个结构组成,同PE那些什么NT头,DOS头的差不多,而所显示的图像数据包函于ICON类型结构的dwImageOffset偏移处。呵,这下总算搞明白为什么直接把ICON文件写入到资源文件中显示不了的问题了,也就是说在dwImageOffset偏移位置处才是咱所需要的图像数据,这不就啥都OK了么,爷爷的,原来咱从一开始就被ICON文件整得稀里糊涂,靠MS,当然也鄙视下自己的无知。另外还好找到的那份资料有点人性,把结构给咱标出来了,那么现在一切都顺理成章,不说多了,上代码:
- #include <stdio.h>
- #include <windows.h>
- #include <tchar.h>
- struct ICONDIRENTRY
- {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bColorCount;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitCount;
- DWORD dwBytesInRes;
- DWORD dwImageOffset;
- };
- struct ICONDIR
- {
- WORD idReserved;
- WORD idType;
- WORD idCount;
- //ICONDIRENTRY idEntries;
- };
- struct GRPICONDIRENTRY
- {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bColorCount;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitCount;
- DWORD dwBytesInRes;
- WORD nID;
- };
- struct GRPICONDIR
- {
- WORD idReserved;
- WORD idType;
- WORD idCount;
- GRPICONDIRENTRY idEntries;
- };
- //
- //函数说明:修改EXE图标
- //
- //参 数:IconFile 图标文件
- // ExeFile 被修改的EXE文件
- //
- //返回值: 成功为True,否则False
- /
- bool ChangeExeIcon(LPWSTR IconFile, LPWSTR ExeFile)
- {
- ICONDIR stID;
- ICONDIRENTRY stIDE;
- GRPICONDIR stGID;
- HANDLE hFile;
- DWORD nSize, nGSize, dwReserved;
- HANDLE hUpdate;
- PBYTE pIcon, pGrpIcon;
- BOOL ret;
- hFile = CreateFile(IconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- return false;
- }
- ZeroMemory(&stID, sizeof(ICONDIR));
- ret = ReadFile(hFile, &stID, sizeof(ICONDIR), &dwReserved, NULL);
- ZeroMemory(&stIDE, sizeof(ICONDIRENTRY));
- ret = ReadFile(hFile, &stIDE, sizeof(ICONDIRENTRY), &dwReserved, NULL);
- nSize = stIDE.dwBytesInRes;
- pIcon = (PBYTE)malloc(nSize);
- SetFilePointer(hFile, stIDE.dwImageOffset, NULL, FILE_BEGIN);
- ret = ReadFile(hFile, (LPVOID)pIcon, nSize, &dwReserved, NULL);
- if (!ret)
- {
- CloseHandle(hFile);
- return false;
- }
- ZeroMemory(&stGID, sizeof(GRPICONDIR));
- stGID.idCount = stID.idCount;
- stGID.idReserved = 0;
- stGID.idType = 1;
- CopyMemory(&stGID.idEntries, &stIDE, 12);
- stGID.idEntries.nID = 0;
- nGSize = sizeof(GRPICONDIR);
- pGrpIcon = (PBYTE)malloc(nGSize);
- CopyMemory(pGrpIcon, &stGID, nGSize);
- hUpdate = BeginUpdateResource(ExeFile, false);
- ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(1), 0, (LPVOID)pGrpIcon, nGSize);
- ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(1), 0, (LPVOID)pIcon, nSize);
- EndUpdateResource(hUpdate, false);
- if (!ret)
- {
- CloseHandle(hFile);
- return false;
- }
- CloseHandle(hFile);
- return true;
- }
VC++编程实现修改EXE文件图标相关推荐
- qt 修改.exe文件图标_如何在没有错误的情况下更改压缩的.EXE文件上的图标
qt 修改.exe文件图标 We've previously shown you how to modify the icon on an .EXE file, but if you've tried ...
- 用UpdateResource修改EXE文件图标的多源码(已修正) 注:转帖请包函作者信息.(作者:菜新)
微软官网UpdateResource 其它参考信息: https://msdn.microsoft.com/zh-cn/library/ms648008.aspx#_win32_Updating_Re ...
- Qt修改exe文件图标
修改Qt生成exe的图标 1. 直接添加.ico 首先要注意的一点是,你的.ico文件不可以是直接用过jpg等图片格式直接修改后缀名形成的,必须是用转换工具来通过jpg转换成ico的格式,不然就会出现 ...
- 使用ICON动态修改exe文件图标
前言:这两天为exe文件做一个随机图标的功能,要求每次运行后图标都动态改变,在网上找了很多代码,都有一部分缺陷,参考了一些文档后进行了修改,现在在此进行总结: 一个icon资源(可以是*.ico文件, ...
- 无源码修改exe文件图标
将exe导入到Restorator里面解析,如果解析不了就用FixRes修复一下 然后导入自己的ico替换即可
- C#怎么修改生成的EXE文件图标
C#怎么修改生成的EXE文件图标 工具/原料 1.VS,Visual Studio 2013或其他版本 2-ico的图标文件一个 方法/步骤 1.打开你的项目文件,如下图,选择release选项 2. ...
- C#上位机开发—— 修改窗口图标和exe文件图标
一.准备应用程序图标 首先寻找一个好看的应用程序图标图片,然后使用在线工具转换为 .ico格式: 二.修改窗口图标 在窗口的属性中找到Icon项,选择要设置的图标即可: 运行后即可看到窗口图标被修改: ...
- 修改exe文件的图标
修改exe文件的图标: 点击项目的属性,找到图标和清单,修改图标就ok,但是图标必须是ico格式的,如下图: jpg转ico: 把jpg格式的图片先用系统自带的画图工具打开,可以调整属性,然后另存为b ...
- 怎么更改exe文件的图标_如何修改EXE文件的图标
怎么更改exe文件的图标 Let's face it: some apps have really ugly icons. Sure, you could always create a shortc ...
最新文章
- Windows中的tree命令不可用的解决办法
- 无论腾讯是自主开放还是被开放,我们都表示欢迎和支持
- 收藏丨运维良药,K8S日常故障处理集锦
- 阿里云消息队列 RocketMQ、Kafka 荣获金融级产品稳定性测评 “先进级” 认证
- Spring中的AOP(三)——基于Annotation的配置方式(一)
- php.ini 只读,disabled by the php.ini setting phar.readonly
- python画决策树
- nginx+tomcat+redis负载均衡及session共享
- 删数问题(Noip1994)
- 第五代移动通信——5G
- 计算机系统结构图并简述各个部件的作用,【计算机组成原理】计算机系统
- MySQL Workbench main_menu.xml 文件 可直接粘贴(下)
- 网站建设费用贵和便宜有什么区别?
- php怎么弄面包屑,php实现面包屑导航例子分享
- 2020-10-11
- linux sfc模拟器,PSP适用SFC模拟器Snes9x完全使用教程
- PreparedStatement的executeQuery、executeUpdate和execute
- PHP处理iso8583报文
- 改造Kindeditor之:自定义图片上传插件。 外加给图片增加水印效果的选择。
- 【数据库系统】规范化