安裝pyinstall
pip install PyInstaller

下載圖標
可以選用阿里的矢量圖,注冊一下,就可以下載了
https://www.iconfont.cn/

下載圖標的格式,選擇png
再百度找一個在線工具,將png圖片,轉換位ico格式
將轉換后的圖片保存的電腦

開始制作exe執行文件
pyinstaller -F -i ./icon/music.ico kuwoMusilDownload.py

因為我的圖標文件和我的py文件不在同一個目錄,所以這里圖標我使用的相對路徑

執行成功輸出
在命令執行目錄會創建一個dist的文件夾,里面放的就是剛剛制作好的exe文件

雙擊執行,程序可以正常運行

擴展
pyinstaller 的參數詳解
-F, onefile 產生一個文件用於部署
-D, onedir 產生一個目錄用於部署
pyinstaller -D kuwoMusilDownload.py 會在dist文件夾內產生一個包含類庫的文件夾,里面也有一個exe文件,可以執行,那么此次執行,所依賴的類庫,均在當前執行目錄內
–i,icon=<FILE.ICO> 為exe文件指定一個ico格式的圖標
其他有需要用的參數,可以百度或執行 pyinstall -h 查看
遇到的問題
1,打包時,報錯【系統無法打開指定的設備或文件。】不要慌,可能是我們用的pycharm 剛剛修改了代碼,還沒來得及自動保存,打包的命令,取文件的時候,被pycharm占用着;稍等一會讓編輯器保存好代碼,在執行打包,就可以了


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

cmd 輸入auto-py-to-exe


會跳出一個可視化程序,點點點就可以了
基於auto-py-to-exe的詳細操作,可以自行百度哦
以上操作都是直接將py打包成exe文件,在敏感信息下,可能會被破解,這里可以使用pyd文件進行打包,防止反編譯
對exe文件進行反編譯
exe反編譯工具:pyinstxtractor.py下載:https://sourceforge.net/projects/pyinstallerextractor/
將pyinstxtractor.py放到exe文件相同目錄
python pyinstxtractor.py main.exe

在當前目錄會生成一個main.exe_extracted的文件夾

解壓出來的 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

運行過程及生成結果如下圖,其中紅框的pyd文件即編譯好了。因為我是64位的系統和python,所以會生成amd64后綴,我們把這個刪掉重命名為batch_get_waybillCodeForCodes.pyd即可。
注:當同時存在mylib.pyd和mylib.py時,引入優先級是pyd>py,所以不用移除py文件,默認引入時就是pyd

創建一個程序入口文件
首先需要創建一個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文件頭部,不然運行會閃退

# -*- 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進行打包,打包程序入口文件

會得到一個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庫是第三方庫,使用時需要額外安裝。

一些常用的功能參數,官方手冊可參考: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
