使用Python修改可执行文件-EXE的图标

这部分网上资料有点太少了…

在做Python 打包工具https://github.com/QPT-Family/QPT(将Python程序打包为EXE)项目的时候,有自定义EXE图标的需求,但QPT走的是SFX方案生成EXE,而且QPT是基于Python打造的,这就使得需要使用使用Python修改EXE的图标。

话不多说,俩方案,一个靠谱的,一个不靠谱的,先讲不靠谱的,因为不靠谱的很方便。

但在此之前,我们需要先准备仨材料:

  1. 生成的EXE
  2. Icon-A(EXE原始的Icon)
  3. Icon-B(需要被替换的Icon)

EXE可以用C++直接生成一个就好,源码可以是:

#include <iostream>
using namespace std;
int main(){
    cout << "Hello 老张" << endl;
    system("pause");
    return 0;
}

icon的话,可以去QPT项目下直接找https://github.com/QPT-Family/QPT ,放在了ext/rc目录下,有俩不像样的icon。

准备基础的文件后,我们还要先了解一些基础的知识~

1. 前置知识

用一句话概括,那就是修改PE(Portable Executable)信息来达到修改图标的目的。

当然,想深入了解PE的话,本文是不会写的,但不妨碍去网上搜索哈哈哈,这里只讲一下怎么修改图标。

首先,我们在构建EXE的时候,指定了一个Icon,这个Icon在生成EXE后会出现哪里呢?
如果你安装了7-zip这样的工具,不妨试试看是否当作压缩包来打开(实际上显示的是类PE结构),打开后如下图所示:
在这里插入图片描述
可以很清晰的看见各部位的偏移、以及其虚拟地址,包括资源大小也是能看到。
这时,我们再打开资源部分(.rsrc),找到ICON所在的资源位置,如下图所示:
在这里插入图片描述

解压后就会发现,这就是EXE的那个Icon!

好了,前置知识已经讲完了,接下来就先是不靠谱的操作了。

2. 方法1 不靠谱,但很方便的资源替换法

我们知道PE中是有1.ico这个文件的,那么我们直接用open()函数打开这个exe文件,直接替换掉这个icon不就可以了吗?
没错,就是这样,非常简单!

exe = r"exe文件"
icon = r"tmp_icon.ico"
icon2 = r"test_icon.ico"

# 二进制方式读取exe
with open(exe, "rb") as f:
    pe = f.read()

# 读取我们生成EXE时候的那个icon文件
with open(icon, "rb") as f:
    ic_b = f.read()

# 读取我们要替换的icon文件
with open(icon2, "rb") as f:
    ic_b2 = f.read()

# 从22的位置开始替换 - 为什么是22?可以自行了解一下图像文件的格式
pe = pe.replace(ic_b[22:], ic_b2[22:])

# 写入硬盘
with open("text3.exe", "wb") as f:
    f.write(pe)

这个方法之所以说不靠谱,是因为所有的资源文件,都有可能会被替换,例如程序中嵌入了一个ico,和应用程序的图标是一个icon,那么pe.replace(ic_b[22:], ic_b2[22:])会一视同仁。

最重要的是,还要考虑替换前后的图像信息长度。

那么接下来就是靠谱的方式了

3. 方法2 使用PeFile库修改图标

这里,非常建议先安装一个ExeScope,因为方便我们查看地址信息,不想安装的话也没什么问题,用PeFile也能打印出结构。

那么我们就先使用ExeScope打开EXE,找到图标所在位置吧~

在这里插入图片描述
然后选择二进制查看
在这里插入图片描述

我们可以看到图标所在的地址起始是0001D6E8,在Python中我们可以表示为0x1D6E8,接下来我们就使用PeFile来修改吧~

pe = pefile.PE(exe)
# offset 可从ExeScope中获取
rva = pe.get_rva_from_offset(0x1D6E8)
pe.set_bytes_at_rva(rva, ic_b2[22:])
f = pe.write()
with open("text4.exe", 'wb') as final_f:
    final_f.write(f)

4. 优化体验 接受jpg、png、bmp等格式的图片作为icon

这部分就得上很强大的pillow了,其实我们的问题不应该是如何让jpg、png、bmp嵌入EXE中,而是让它们变成ico格式就好,代码很简单:

    img = Image.open(img_path).resize((128, 128))
    img.save(ico_save_path, sizes=[(128, 128)])

参考链接

Python打包工具-QPT

在QPT中,对应的代码位置为:https://github.com/QPT-Family/QPT/blob/开发分支/qpt/kernel/qpe.py ,如有变动请自行在QPT中查找~

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Django的测试质量平台:目前包含数据工厂、接口自动化,后续规划:设备管理、代码覆盖率统计、app打包平台、发布流程、项目管理...<br> <br> 目标是做成最好用、最全面的测试质量平台,先介绍下已有的两个平台情况<br> <br> 数据工厂平台:本篇只是造数据的事务管理平台,还需要搭建一套基于spring框架,封装开发dubbo接口集合的后端平台,再通过DataManager平台调用后端平台的http接口实现造数据功能。参考demo: <a href="https://github.com/DataFactorys/xinyu-qacenter" title="Title">http接口接入平台</a><br> <br> Key Features ------------ - 项目管理:新增、编辑、删除项目、列表展示及相关操作 - 模块管理:新增、编辑、删除模块,为项目新增模块 - 添加事务模板:自定义添加事务模板,自定义入参 - 我的事务模板:铺开展示用户本人添加的事务,方便查看、编辑 - 全部事务:所有事务铺开展示,可以执行调用接口、收藏事务 - 常用事务:按调用量统计显示前10的常用事务 - 我的收藏:显示用户本人收藏的事务 - 环境管理:可添加运行环境,运行用例时可以一键切换环境 - 调用历史:查看事务被调用情况 - 调用量统计:图标展示所有事务被调用情况 本地开发环境部署 -------- 1. 安装mysql数据库服务端(推荐5.7+),并设置为utf-8编码,排序规则utf8_general_ci,创建相应qacenter数据库,设置好相应用户名、密码,启动mysql 2. 修改:qacenter/qacenter/settings.py里DATABASES字典和邮件发送账号相关配置 -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值