IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Windows在PyCharm使用PyInstaller打包Python项目

    SparkAndShine发表于 2021-07-19 22:27:19
    love 0

    本文记录在Windows上,使用PyCharm打包Python项目的操作。

    1. 安装pyinstaller

    打开PyCharm的设置,File --> Settings --> Python Interpreter,选择环境,点击+,搜索pyinstaller,点击安装。

    2. 打包可执行文件

    2.1 通过命令行打包

    pyinstaller [options] script [script …] | specfile

    在PyCharm,打开终端Terminal,输入命令pyinstaller命令,举例:

    pyinstaller --icon icon.ico --name "芝麻酱"  -F main.py scrapyimages.py --add-data "fake_useragent_0.1.11.json;." --add-binary "C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll;."

    一些常用的选项:

    -F, --onefile       打包成一个文件
    -i, --icon          可执行程序的图标    
    -n, --name          可执行程序文件名
    -w, --noconsole     不显示控制台
    -d, --debug         带调试信息
    --add-data          添加依赖文件
    --add-binary        添加库

    PyInstaller更多用法见:Using PyInstaller — PyInstaller documentation。另:

    • icon转换工具:Icon Converter | Convert Image to ICO File Online – RedKetchup
    • 更换环境,在终端使用命令conda activate [myenv]

    执行pyinstaller options.. myscript.py,PyInstaller会创建一个规范说明文件name.spec(specification file)。事实上,运行pyinstaller的参数都在这里。因此,更建议直接在name.spec上修改,再打包。

    2.2 通过规范说明文件打包

    可以使用pyinstaller -F main.py生成main.spec,再编辑该文件:

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    a = Analysis(['main.py', 'scrapyimages.py'],
                 pathex=['D:\\workspace\\images_crawler\\src'],
                 binaries=[('C:\\Anaconda3\\Library\\bin\\mkl_intel_thread.1.dll', '.')],
                 datas=[('D:\\workspace\\images_crawler\\src\\fake_useragent_0.1.11.json', '.')],
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              [],
              name='芝麻酱',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              upx_exclude=[],
              runtime_tmpdir=None,
              console=True , icon='icon.ico')

    然后运行:

    pyinstaller -F main.spec

    关于规范说明文件说见:Using Spec Files — PyInstaller documentation。

    3. 遇到问题及解决

    (1)Cannot load mkl_intel_thread.1.dll

    打包完,双击.exe文件,控制台输出错误:

    Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.1.dll

    在电脑上找到mkl_intel_thread.1.dll的位置,C:\Anaconda3\Library\bin\mkl_intel_thread.1.dll,将该动态库添加到main.spec

    (2)软件需要外部数据

    我打包的这个应用,用到这个文件fake_useragent_0.1.11.json,打包时,不能用相对路径,原因是[1]:

    运行可执行文件时,会先将可执行文件进行压缩再执行,压缩的位置在 /tmp 下。因此,被打包进去的数据文件在被解压的路径下,而程序是在运行的路径下搜索,即可执行文件的目录下,所以找不到数据文件。

    因此,我这样处理:

    from fake_useragent import UserAgent
    
    #ua = UserAgent(path='./fake_useragent_0.1.11.json')
    
    cur_dir = os.path.dirname(os.path.abspath(__file__))
    ua = UserAgent(path = os.path.join(cur_dir, 'fake_useragent_0.1.11.json'))

    (3)运行完退出

    程序运行完,控制台就关了。想让控制台在程序执行完不关闭,方法很多。

    • 在main()函数末尾加上input('按任意键关闭窗口')
    • 在main()函数末尾加上os.system('pause')
    • 打开cmd,运行可执行文件

    (4)程序运行一会,退出,没有错误信息

    我将打包好的可执行文件放到其他电脑运行,双击后,运行一会,就退出,没有错误信息,也不是闪退。首先,加上-d选项,重新打包成带有调试信息的可执行文件。再次运行,得到如下信息:

    C:\Users\admin\Desktop>芝麻酱.exe
    [11884] PyInstaller Bootloader 3.x
    [11884] LOADER: executable is C:\Users\admin\Desktop\芝麻酱.exe
    ...
    [4100] LOADER: Running pyi_rth_pyqt5.py
    [4100] LOADER: Running pyi_rth_mplconfig.py
    [4100] LOADER: Running pyi_rth_mpldata.py
    [4100] LOADER: Running pyi_rth_certifi.py
    [4100] LOADER: Running pyi_rth__tkinter.py
    [4100] LOADER: Running main.py
    [11884] LOADER: Back to parent (RC: -1066598274)
    [11884] LOADER: Doing cleanup
    [11884] LOADER: Freeing archive status for C:\Users\admin\Desktop\芝麻酱.exe

    我估计问题出在tkinter包,搜索了下,说是缺少libiomp5md.dll[2]。在Anaconda目录搜索该文件,找到C:\Anaconda3\Library\bin\libiomp5md.dll,将libiomp5md.dll拷贝到main.py同一个目录下,并添加到spec文件的datas中,重新打包文件。

    datas=[('libiomp5md.dll', '.')]

    遗憾的是,问题依旧,知道方法的,烦请留言告知。

    参考文献:

    [1] Pyinstaller将外部数据文件打包到可执行文件中(onefolder or onefile)教程_m0_37477175的博客-CSDN博客

    [2] python – PyInstaller .exe file terminates early without an error message – Stack Overflow



沪ICP备19023445号-2号
友情链接