將Python模塊用pyinstaller打包成exe程序
-
下載安裝UPX((http://upx.sourceforge.net/) ) ,並把路徑加到環境變量中。
UPX是開源的加殼和壓縮exe的程序,使用UPX能有效減小發布的exe文件體積。
-
安裝PyInstaller:
pip install pyinstaller
python setup.py build_ext --inplace
setup.py是我們要調用的Python模塊安裝入口,它主要包含Python模塊的依賴項和要打包的文件清單。
- 使用pyinstaller打包python程序。
Pyinstaller基本使用方法
Pyinstaller可以通過簡單的命令進行python代碼的打包工作,其基本的命令為:
pyinstaller -option xxx.py
options的詳情可參考官方幫助文檔https://pyinstaller.readthedocs.io/en/stable/usage.html
這邊只介紹用到的option:-d生成一個文件目錄包含可執行文件和相關動態鏈接庫和資源文件等;
-f僅生成一個可執行文件
-D, --onedir Create a one-folder bundle containing an executable (default)
-F, --onefile Create a one-file bundled executable.
對於打包結果較大的項目,選用-d生成目錄相比單可執行文件的打包方式,執行速度更快,但包含更加多的文件。本文的例子選中-d方式打包。
Python項目的打包方法
1.spec文件生成
為了進行自定義配置的打包,首先需要編寫打包的配置文件.spec文件。當使用pyinstaller -d xxx.py時候會生成默認的xxx.spec文件進行默認的打包配置。通過配置spec腳本,並執行pyinstaller -d xxx.spec完成自定義的打包。
通過生成spec文件的命令,針對代碼的主程序文件生成打包對應的spec文件
pyi-makespec -w xxx.py
打開生成的spec文件,修改其默認腳本,完成自定義打包需要的配置。spec文件是一個python腳本,其默認的結構如下例所示
# -*- mode: python -*-
block_cipher = None
a = Analysis(['fastplot.py'],
pathex=['D:\\install_test\\DAGUI-0.1\\bin'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='fastplot',
debug=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='fastplot')
spec文件中主要包含4個class: Analysis, PYZ, EXE和COLLECT.
- Analysis以py文件為輸入,它會分析py文件的依賴模塊,並生成相應的信息
- PYZ是一個.pyz的壓縮包,包含程序運行需要的所有依賴
- EXE根據上面兩項生成
- COLLECT生成其他部分的輸出文件夾,COLLECT也可以沒有
2.spec文件配置
a) py文件打包配置
針對多目錄多文件的python項目,打包時候需要將所有相關的py文件輸入到Analysis類里。Analysis類中的pathex定義了打包的主目錄,對於在此目錄下的py文件可以只寫文件名不寫路徑。如上的spec腳本,將所有項目中的py文件路徑以列表形式寫入Analysis,這里為了說明混合使用了絕對路徑和相對路徑。
b) 資源文件打包配置
資源文件包括打包的python項目使用的相關文件,如圖標文件,文本文件等。對於此類資源文件的打包需要設置Analysis的datas,datas接收元組:datas=[(SETUP_DIR+‘lib\icon’,‘lib\icon’),(SETUP_DIR+‘data’,‘data’)]。元組的組成為(原項目中資源文件路徑,打包后路徑)。
c)Hidden import配置
pyinstaller在進行打包時,會解析打包的python文件,自動尋找py源文件的依賴模塊。但是pyinstaller解析模塊時可能會遺漏某些模塊(not visible to the analysis phase),造成打包后執行程序時出現類似No Module named xxx。這時我們就需要在Analysis下hiddenimports中加入遺漏的模塊,如例子中所示。
d)遞歸深度設置
在打包導入某些模塊時,常會出現"RecursionError: maximum recursion depth exceeded"的錯誤,這可能是打包時出現了大量的遞歸超出了python預設的遞歸深度。因此需要在spec文件上添加遞歸深度的設置,設置一個足夠大的值來保證打包的進行,即
import sys
sys.setrecursionlimit(5000)
3.使用pyinstaller命令執行 spec配置打包
pyinstaller -D xxx.spec
打包生成兩個文件目錄build和dist,build為臨時文件目錄完成打包后可以刪除;dist中存放打包的結果,可執行文件和其它程序運行的關聯文件都在這個目錄下。
注意:要打包的python模塊的依賴項比如numpy等最好在pyinstaller安裝之前,可避免生成錯誤。
c#調用pyinstaller打包的exe程序
- 將pyinstaller打包后的dist文件下的內容添加到c#項目中
- c#調用exe代碼:
using (Process proc = new Process())
{
proc.StartInfo.FileName = "/path/打包后的exe名稱.exe";
proc.StartInfo.Arguments = “exe參數”;
proc.StartInfo.RedirectStandardError = true;
proc.Start();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
}
上述FileName是打包后的exe絕對路徑。error是控制台輸出的錯誤信息,如果程序出錯的話。
本人之前的項目HtwMedia(https://blog.csdn.net/u014220286/article/details/88895867)中就用到了這種調用方式,避免了重寫python模塊帶來的繁重工作量。