如何识别PyInstaller打包生成的exe中内置的Python库版本?
以下方法不需要原始构建命令、原构建环境或requirements文件,直接基于现有exe及配套dll、pyd文件即可完成识别,按准确率和操作成本从优到劣排序:
方法1:读取PyInstaller打包时内置的dist-info元数据(准确率100%,优先使用)
你当前拿到的是目录模式的打包产物(exe和dll、pyd文件放在同一目录),直接在exe同级目录找lib文件夹,逐层进入对应Python版本的site-packages子目录,所有第三方依赖都会对应一个格式为包名-版本号.dist-info的文件夹,比如numpy-1.24.3.dist-info、pandas-2.0.2.dist-info,文件夹名中标注的版本号就是打包时绑定的准确版本。
如果遇到单文件打包的exe,先双击运行程序且不要关闭,打开Windows临时目录(资源管理器地址栏输入%temp%回车即可进入),找到_MEI开头的随机命名临时文件夹,进入后按上述路径找dist-info目录即可查询,注意该临时文件夹会在exe关闭后自动删除,需在程序运行状态下操作。方法2:读取二进制文件内置版本信息(无需运行程序)
如果dist-info目录被人为删除,可以直接定位对应库的核心pyd/dll文件:比如numpy对应numpy.core._multiarray_umath.pyd,pandas对应带pandas标识的核心pyd文件,右键点击文件选择「属性-详细信息」,「文件版本」「产品版本」字段即为对应库的版本号。
部分未写入Windows版本资源的文件,可以用strings工具扫描文件内的字符串,执行命令strings 目标文件路径 | findstr "__version__",即可提取到文件内硬编码的版本标识。方法3:运行时hook自动输出全量依赖版本(适用于元数据缺失的场景)
在exe同级目录新建名为sitecustomize.py的文件,写入以下代码:import pkg_resources # 启动时遍历所有已安装依赖,写入结果文件 with open("dependency_versions.txt", "w", encoding="utf-8") as f: for dist in pkg_resources.working_set: f.write(f"{dist.key}=={dist.version}\n")正常双击运行原exe,程序启动时会自动加载该脚本,运行完成后同目录下会生成
dependency_versions.txt,里面就是所有绑定依赖的完整版本清单,查询完成后删除该py文件即可,不会对原程序造成任何修改。
注意:不要随意替换打包目录下的pyd/dll文件做版本测试,PyInstaller打包的二进制文件存在ABI绑定,版本不匹配会直接导致程序崩溃,优先选择前两种无侵入方法。
内容的提问来源于stack exchange,提问作者colormask

