Python 打包成单体exe可执行文件

安装pyinstall

pip install PyInstaller
image

下载图标

可以选用阿里的矢量图,注册一下,就可以下载了
https://www.iconfont.cn/
image
下载图标的格式,选择png
再百度找一个在线工具,将png图片,转换位ico格式
将转换后的图片保存的电脑
image

开始制作exe执行文件

pyinstaller -F -i ./icon/music.ico kuwoMusilDownload.py
image
因为我的图标文件和我的py文件不在同一个目录,所以这里图标我使用的相对路径
image
执行成功输出
在命令执行目录会创建一个dist的文件夹,里面放的就是刚刚制作好的exe文件
image
双击执行,程序可以正常运行
image

扩展

pyinstaller 的参数详解

-F, onefile 产生一个文件用于部署
-D, onedir 产生一个目录用于部署
pyinstaller -D kuwoMusilDownload.py 会在dist文件夹内产生一个包含类库的文件夹,里面也有一个exe文件,可以执行,那么此次执行,所依赖的类库,均在当前执行目录内
–i,icon=<FILE.ICO> 为exe文件指定一个ico格式的图标
其他有需要用的参数,可以百度或执行 pyinstall -h 查看

遇到的问题

1,打包时,报错【系统无法打开指定的设备或文件。】不要慌,可能是我们用的pycharm 刚刚修改了代码,还没来得及自动保存,打包的命令,取文件的时候,被pycharm占用着;稍等一会让编辑器保存好代码,在执行打包,就可以了
image
image
2,如果引用了空的第三方库,程序里没用到的,可能不会被打进exe里,那么在程序执行的时候,就会闪退,因为开头引用了,但实际exe中却没有,我遇到过,去掉就可以了
3,如果引用的第三方库,在pycharm执行时是没有问题的,打包之后,错误显示,找不到某个库,可能原因是你只在pycharm安装了这个库,而没有在电脑上安装这个,在cmd或者powershell执行pip install xx 进行安装后,在打包,打包完之后,还不行,还是显示找不到某个库,应该是第二次打包时,用的还是第一次的缓存,需要修改一下py文件,更新掉缓存,再次打包的时候,会从计算机中重新加载所有的库,进行打包
4,exe文件执行时闪退的调试,可以在exe所在的文件夹 shift+右键 在此处打开powershell;执行.\exe文件名;控制台会输出具体的报错原因,然后根据原因进行解决,就可以了
5,ERROR: Could not install packages due to an OSError: [WinError 2] 系统找不到指定的文件;使用管理员终端进行执行(win+R进入黑窗口):python -m pip install --upgrade pip
6,win32ctypes.pywin32.pywintypes.error: (110, 'EndUpdateResourceW', '系统无法打开指定的设备或文件。');也是要使用管理员权限

pyinstaller 可视化打包

pip install auto-py-to-exe
image
cmd 输入auto-py-to-exe
image
image
会跳出一个可视化程序,点点点就可以了
基于auto-py-to-exe的详细操作,可以自行百度哦

以上操作都是直接将py打包成exe文件,在敏感信息下,可能会被破解,这里可以使用pyd文件进行打包,防止反编译

对exe文件进行反编译

exe反编译工具:pyinstxtractor.py下载:https://sourceforge.net/projects/pyinstallerextractor/
将pyinstxtractor.py放到exe文件相同目录
python pyinstxtractor.py main.exe
image
在当前目录会生成一个main.exe_extracted的文件夹
image
解压出来的 pyd文件就是源代码编译后的文件,这种pyd的文件,是很难被反编译的,达到保护源码的目的
如果没有经过编译后的文件,直接解压,会出现一个不带后缀名的源文件,那个是pyc文件,可以被反编译成原py文件。

对py文件进行pyc处理,然后在进行exe输出

将py文件编译为动态链接库,这样破解难度将大大增加。其中,在python里,pyd格式即动态链接库。使用cython即可编译为pyd文件。
首先安装cpython
pip install Cython
目录结构
新建build_pyd.py文件

# -*- ecoding: utf-8 -*-
# @ModuleName: build_pyd
# @Function: 
# @Author: darling
# @Time: 2022-11-12 14:58

# -*- coding: utf-8 -*-

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name='any words.....',
    ext_modules=cythonize(["batch_get_waybillCodeForCodes.py", ]
                          ),
)

cmd 中执行这个命令
python .\build_pyd.py build_ext --inplace
image
运行过程及生成结果如下图,其中红框的pyd文件即编译好了。因为我是64位的系统和python,所以会生成amd64后缀,我们把这个删掉重命名为batch_get_waybillCodeForCodes.pyd即可。
注:当同时存在mylib.pyd和mylib.py时,引入优先级是pyd>py,所以不用移除py文件,默认引入时就是pyd
image

创建一个程序入口文件

首先需要创建一个main.py文件,其作为一个入口程序来导入pyd文件,pyd文件默认优先级高于py文件,因此batch_get_waybillCodeForCodes.py和batch_get_waybillCodeForCodes.pyd可以同时存在,也就是说batch_get_waybillCodeForCodes.py不需要删除也不能删除,删除了程序入库main.py文件会报错,
注意:
1、程序的__main__入口只能有一个,如果源py文件中有定义main入口,需要注释掉并调整代码缩进,否则通过main.py调用pyd文件遇到if name == ‘main’:之后的代码都不会运行。
2、源文件batch_get_waybillCodeForCodes.py文件头部import到的第三方库需全部复制到main.py文件头部,不然运行会闪退

image

# -*- ecoding: utf-8 -*-
# @ModuleName: main
# @Function: 
# @Author: darling
# @Time: 2022-11-12 15:21
import hashlib
import json
import math
import os
import sys
import time
import urllib.parse
from concurrent.futures import ThreadPoolExecutor

import execjs
import requests
from loguru import logger

sys.path.append('cron/message_dic.py')
from cron.message_dic import message as msg

global client
client = ''
global token
token = ''
global user
user = ''
global pro, cus, username

global result
result = {}


import batch_get_waybillCodeForCodes

if __name__ == '__main__':
    batch_get_waybillCodeForCodes()

然后用pyinstaller进行打包,打包程序入口文件
image
会得到一个main.exe文件,可以进行运行试试,逻辑应该是源文件的逻辑

我们测试,用python pyinstxtractor.py main.exe进行解包,得到的对应的文件为.pyd 则表示加密成功

参考博文

Pyinstaller打包python程序遇到的一些问题

一. Pyinstaller简要介绍
二. Pyinstaller打包的一些问题
2.1. 打包cpca模块无法解析
2.2. 打包jieba模块无法解析
2.3. 安装pyzbar模块
2.4. 打包Tranformer模块的问题
2.5. 打包过程中一些库文件缺失(重要)以及打包性能
2.6. 打包有参数传递的程序
2.7. Pyinstaller打包过程中加密
三. Win和Linux系统下打包
3.1. Linux系统下对程序进行打包
3.2. Win系统下对程序进行打包
3.3. 查看Linux系统是Centos还是Ubuntu
四. Cython编辑Python为动态库
五. PyArmor加密技术
六. 参考文章

Pyinstaller简要介绍

PyInstaller是一个 能将Python程序转换成单个可执行文件的程序,操作系统支持Windows, Linux, Mac OS X, Solaris和AIX。PyInstaller库是第三方库,使用时需要额外安装。

image
一些常用的功能参数,官方手册可参考:https://pyinstaller.readthedocs.io/en/stable/

参数 含义
-F(重要) 生成结果是一个exe程序,所有第三方依赖库和其他资源都被打包进该exe程序中 (-F会压缩包,占用空间小,但是执行的时候需要先解压,所以启动速度慢,不加-F启动快,但是占用空间大)
-distpath 指定打包后的程序存放目录,默认存放在当前目录下的dist目录
-workpath 指定编译过程中临时文件的存放位置
-D 生成结果是一个包含exe程序的目录,所有第三方依赖库和其他资源和exe程序位于同一目录下(默认条件就是这个)
-i 指定可执行文件的图标(只对windows系统有效)
-p 指定可执行文件依赖的包和模块,如 -p “/usr/local/lib/python3.5/dist-packages”
-d 编译为debug模式,获取运行中的日志信息
-clean 在构建之前,清理PyInstaller缓存并删除临时文件。即清空build目录里的文件
-c 使用控制台,默认模式
-w(重要) 不使用控制台
--version-file 添加版本信息
-y(重要) 如果dist文件夹内已经存在生成文件,则不询问用户直接覆盖
--key(重要) 对打包进行加密,则会提示安装 pip install tinyaes,如pyinstaller -F —key ‘12345678’ —clean main.py
--add-data(重要) 要添加到可执行文件的其他非二进制文件或文件夹。使用路径分隔符是特定于平台的os.pathsep(;在 Windows 和:大多数 unix 系统上)。此选项可以多次使用。
--copy-metadata(重要) 复制指定包的元数据。此选项可以多次使用。

使用 PyInstaller(官方手册):https://pyinstaller.readthedocs.io/en/stable/usage.html

转载文章,这里写的很好,罗列了部分打包错误的问题,可以参考

posted @ 2022-02-12 18:55  darling331  阅读(1371)  评论(0编辑  收藏  举报