pyinstaller打包exe後無法執行錯誤解決

1、執行環境說明
python版本3.7
直接使用pip進行安裝pywin32、pyinstaller
pip install pywin32
pip install pyinstaller

2、使用了第三方庫的情況
建議在打包之前務必找到第三方庫的包,把包複製到到跟myfile.py同目錄下,然後再使用以上2種方式打包,否則會打包失敗或者即使打包成功,程序也會閃退。pyinstaller -p參數是添加的pyinstaller打包程序時的掃描路徑,假設venv\Lib\site-packages是包存放路徑,那麼也可以使用以下命令打包:

pyinstaller -p venv\Lib\site-packages -F xxx.py

3、failed to execute script 錯誤,缺少依賴庫。
首先使用
pyinstaller -F -w code.py
進行exe打包,得到的單個.exe文件,運行後提示failed to execute script 錯誤
排錯過程:使用pyinstaller -D code.py進行exe打包,得到一個目錄文件,通過命令行執行.exe文件提示The 'six' package is required; normally this is bundled with this package錯誤
說明pyinstaller打包後,需要six等庫,最終確認需要在code.py中添加以下庫:
import six
import packaging
import packaging.version
import packaging.specifiers
import packaging.requirements
當然,six和packaging庫建議使用pip安裝。加入以上庫後,使用pyinstaller -D code.py打包執行不再出錯。

另:1)pyinstaller -p 庫路徑 ,-p參數是導入庫的目錄,將會將該庫路徑下的庫都打包進來

     2) --hidden-import 包名, 將導入指定隱藏庫

這兩種方法都可以將需要的庫打包進去.

4、failed to execute script 錯誤,使用pyinstaller -D code.py進行exe打包,執行後提示 “unable to find Qt5Core.dll on PATH”,如下圖:

參考:https://stackoverflow.com/questions/56949297/how-to-fix-importerror-unable-to-find-qt5core-dll-on-path-after-pyinstaller-b

https://github.com/pyinstaller/pyinstaller/issues/4293

pyqt5庫對系統變量的加載存在bug,在主程序中pyqt5庫import之前就對系統變量進行手動設置,import代碼如下:

import sys, os
if hasattr(sys, 'frozen'):
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']

5、failed to execute script 錯誤,使用pyinstaller -D code.py進行exe打包,執行後提示 ImportError: DLL load failed while importing win32api: 找不到指定的模塊。

上面的錯誤,就是import win32api,打包後缺少運行dll引起的。

將python\Lib\site-packages\pywin32_system32中的dll文件拷貝過來就行了。

6、找不到數據文件夾

有些程序包含了數據文件夾,不能直接按資源文件方式打包,需要在執行文件所在的文件夾內創建這些數據文件。一般情況下在腳本中我們可以使用os.path.split(os.path.abspath( __file__))來的到code.py的路徑,然後拼接得到數據文件夾。但之後使用pyinstaller -F code.py打包成單個exe文件,在未讀取數據文件夾的情況下運行正常,一旦打開數據文件,就會閃退,命令行窗口會顯示打不開數據文件。因爲PyInstaller會創建臨時文件夾temp,程序代碼在這個臨時文件夾中運行,我們可以用以下幾個語句來查看正式運行路徑:
    import sys
    import os
    print(sys.path[0])
    print(sys.argv[0])
    print(os.path.dirname(os.path.realpath(sys.executable)))
    print(os.path.dirname(os.path.realpath(sys.argv[0])))

得到的結果是os.path.dirname(os.path.realpath(sys.executable))和os.path.dirname(os.path.realpath(sys.argv[0]))纔是含數據文件夾的路徑。因此可以按如下方式取得文件路徑,然後根據需要拼接得到數據文件夾的真實路徑:
    if hasattr(sys, '_MEIPASS'):
    # PyInstaller會創建臨時文件夾temp
    # 並把路徑存儲在_MEIPASS中
        self.appPath = os.path.dirname(os.path.realpath(sys.executable))
    else:
        self.appPath, filename = os.path.split(os.path.abspath( __file__))

修改完成後,分別以以下三種方式打包,運行成功
pyinstaller -D code.py
pyinstaller -F code.py
pyinstaller -w -F code.py

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章