python程序打包exe详解pyinstaller

打包功能介绍pyinstaller

使用python写的程序,往往需要python解释器支持运行,一般电脑有都有。即使这样我们也不会说就直接拿源码去让别人运行。一般我们使用pyinstaller进行一个简单的打包,这样程序运行的依赖就都打到一起了,在哪里都能正常运行,还有的时候我们甚至会直接打包成一个exe,这样文件就是一个整体,而不是很多个散文件,源码也相对没那么开放。那么下面详细看看pyinstaller都有哪些功能,适应哪些场景。

pyinstaller安装

Python 默认并不包含 PyInstaller 模块,我们一般可以使用pip安装,不管是什么ide,基本都支持开启终端命令模式:terminal。执行下面的语句,结果是success就可以了,有的时候会弹出一些更新source或者其他的信息,只要我们的pyinstaller安装成功,其他的都不影响。

pip install pyinstaller

执行pyinstaller --version ,提示正确的版本号,就说明安装成功了,一般也不会出什么错,就不细说了,有什么问题解决什么问题就可以了。也欢迎留言提问。

简单的使用

其实很多开源的库都做的很好,python的这个库也是,不会用的时候使用命令-h或者–help,会有详细的使用说明出来。

pyinstaller --help   
usage: pyinstaller [-h] [-v] [-D] [-F] [--specpath DIR] [-n NAME] [--add-data <SRC;DEST or SRC:DEST>] [--add-binary <SRC;DEST or SRC:DEST>] [-p DIR] [--hidden-import MODULENAME] [--collect-submodules MODULENAME] [--collect-data MODULENAME] [--collect-binaries MODULENAME] [--collect-all MODULENAME]
                   [--copy-metadata PACKAGENAME] [--recursive-copy-metadata PACKAGENAME] [--additional-hooks-dir HOOKSPATH] [--runtime-hook RUNTIME_HOOKS] [--exclude-module EXCLUDES] [--key KEY] [--splash IMAGE_FILE] [-d {all,imports,bootloader,noarchive}] [--python-option PYTHON_OPTION] [-s] [--noupx]
                   [--upx-exclude FILE] [-c] [-w] [-i <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">] [--disable-windowed-traceback] [--version-file FILE] [-m <FILE or XML>] [--no-embed-manifest] [-r RESOURCE] [--uac-admin] [--uac-uiaccess] [--win-private-assemblies] [--win-no-prefer-redirects]      
                   [--argv-emulation] [--osx-bundle-identifier BUNDLE_IDENTIFIER] [--target-architecture ARCH] [--codesign-identity IDENTITY] [--osx-entitlements-file FILENAME] [--runtime-tmpdir PATH] [--bootloader-ignore-signals] [--distpath DIR] [--workpath WORKPATH] [-y] [--upx-dir UPX_DIR] [-a] [--clean]   
                   [--log-level LEVEL]
                   scriptname [scriptname ...]

positional arguments:
  scriptname            Name of scriptfiles to be processed or exactly one .spec file. If a .spec file is specified, most options are unnecessary and are ignored.

options:
  -h, --help            show this help message and exit
  -v, --version         Show program version info and exit.
  --distpath DIR        Where to put the bundled app (default: ./dist)
  --workpath WORKPATH   Where to put all the temporary work files, .log, .pyz and etc. (default: ./build)
  -y, --noconfirm       Replace output directory (default: SPECPATH\dist\SPECNAME) without asking for confirmation
  --upx-dir UPX_DIR     Path to UPX utility (default: search the execution path)
  -a, --ascii           Do not include unicode encoding support (default: included if available)
  --clean               Clean PyInstaller cache and remove temporary files before building.
  --log-level LEVEL     Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).

What to generate:
  -D, --onedir          Create a one-folder bundle containing an executable (default)
  -F, --onefile         Create a one-file bundled executable.
  --specpath DIR        Folder to store the generated spec file (default: current directory)
  -n NAME, --name NAME  Name to assign to the bundled app and spec file (default: first script's basename)

What to bundle, where to search:
  --add-data <SRC;DEST or SRC:DEST>
                        Additional non-binary files or folders to be added to the executable. The path separator is platform specific, ``os.pathsep`` (which is ``;`` on Windows and ``:`` on most unix systems) is used. This option can be used multiple times.
  --add-binary <SRC;DEST or SRC:DEST>
                        Additional binary files to be added to the executable. See the ``--add-data`` option for more details. This option can be used multiple times.
  -p DIR, --paths DIR   A path to search for imports (like using PYTHONPATH). Multiple paths are allowed, separated by ``';'``, or use this option multiple times. Equivalent to supplying the ``pathex`` argument in the spec file.
  --hidden-import MODULENAME, --hiddenimport MODULENAME
                        Name an import not visible in the code of the script(s). This option can be used multiple times.
  --collect-submodules MODULENAME
                        Collect all submodules from the specified package or module. This option can be used multiple times.
  --collect-data MODULENAME, --collect-datas MODULENAME
                        Collect all data from the specified package or module. This option can be used multiple times.
  --collect-binaries MODULENAME
                        Collect all binaries from the specified package or module. This option can be used multiple times.
  --collect-all MODULENAME
                        Collect all submodules, data files, and binaries from the specified package or module. This option can be used multiple times.
  --copy-metadata PACKAGENAME
                        Copy metadata for the specified package. This option can be used multiple times.
  --recursive-copy-metadata PACKAGENAME
                        Copy metadata for the specified package and all its dependencies. This option can be used multiple times.
  --additional-hooks-dir HOOKSPATH
                        An additional path to search for hooks. This option can be used multiple times.
  --runtime-hook RUNTIME_HOOKS
                        Path to a custom runtime hook file. A runtime hook is code that is bundled with the executable and is executed before any other code or module to set up special features of the runtime environment. This option can be used multiple times.
  --exclude-module EXCLUDES
                        Optional module or package (the Python name, not the path name) that will be ignored (as though it was not found). This option can be used multiple times.
  --key KEY             The key used to encrypt Python bytecode.
  --splash IMAGE_FILE   (EXPERIMENTAL) Add an splash screen with the image IMAGE_FILE to the application. The splash screen can display progress updates while unpacking.

How to generate:
  -d {all,imports,bootloader,noarchive}, --debug {all,imports,bootloader,noarchive}
                        Provide assistance with debugging a frozen
                        application. This argument may be provided multiple
                        times to select several of the following options.

                        - all: All three of the following options.

                        - imports: specify the -v option to the underlying
                          Python interpreter, causing it to print a message
                          each time a module is initialized, showing the
                          place (filename or built-in module) from which it
                          is loaded. See
                          https://docs.python.org/3/using/cmdline.html#id4.

                        - bootloader: tell the bootloader to issue progress
                          messages while initializing and starting the
                          bundled app. Used to diagnose problems with
                          missing imports.

                        - noarchive: instead of storing all frozen Python
                          source files as an archive inside the resulting
                          executable, store them as files in the resulting
                          output directory.

  --python-option PYTHON_OPTION
                        Specify a command-line option to pass to the Python interpreter at runtime. Currently supports "v" (equivalent to "--debug imports"), "u", and "W <warning control>".
  -s, --strip           Apply a symbol-table strip to the executable and shared libs (not recommended for Windows)
  --noupx               Do not use UPX even if it is available (works differently between Windows and *nix)
  --upx-exclude FILE    Prevent a binary from being compressed when using upx. This is typically used if upx corrupts certain binaries during compression. FILE is the filename of the binary without path. This option can be used multiple times.

Windows and Mac OS X specific options:
  -c, --console, --nowindowed
                        Open a console window for standard i/o (default). On Windows this option has no effect if the first script is a '.pyw' file.
  -w, --windowed, --noconsole
                        Windows and Mac OS X: do not provide a console window for standard i/o. On Mac OS this also triggers building a Mac OS .app bundle. On Windows this option is automatically set if the first script is a '.pyw' file. This option is ignored on *NIX systems.
  -i <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">, --icon <FILE.ico or FILE.exe,ID or FILE.icns or Image or "NONE">
                        FILE.ico: apply the icon to a Windows executable. FILE.exe,ID: extract the icon with ID from an exe. FILE.icns: apply the icon to the .app bundle on Mac OS. If an image file is entered that isn't in the platform format (ico on Windows, icns on Mac), PyInstaller tries to use Pillow to    
                        translate the icon into the correct format (if Pillow is installed). Use "NONE" to not apply any icon, thereby making the OS show some default (default: apply PyInstaller's icon)
  --disable-windowed-traceback
                        Disable traceback dump of unhandled exception in windowed (noconsole) mode (Windows and macOS only), and instead display a message that this feature is disabled.
Rarely used special options:
  --runtime-tmpdir PATH
                        Where to extract libraries and support files in `onefile`-mode. If this option is given, the bootloader will ignore any temp-folder location defined by the run-time OS. The ``_MEIxxxxxx``-folder will be created here. Please use this option only if you know what you are doing.
  --bootloader-ignore-signals
                        Tell the bootloader to ignore signals rather than forwarding them to the child process. Useful in situations where for example a supervisor process signals both the bootloader and the child (e.g., via a process group) to avoid signalling the child twice.

最简单的打包指令

一句话就可以执行打包了,这个指令打包出来一个文件夹,在工程的dist目录下,和指定的py同名。打包的时候只需要指定一个python文件,打包程序就会把和这个文件相关的所有文件全包打包出来,自己分析依赖,所以打包的时候只需要指定有主函数的那个文件就可以了。

pyinstaller.exe .\main.py

打包选项-F还是-D

在帮助里面有这一段,确认是生成什么,这里有四个可以选择的选项。其中-D,-F是互斥的。

What to generate:
  -D, --onedir          Create a one-folder bundle containing an executable (default)
  -F, --onefile         Create a one-file bundled executable.
  --specpath DIR        Folder to store the generated spec file (default: current directory)
  -n NAME, --name NAME  Name to assign to the bundled app and spec file (default: first script's basename)

-D 生成的文件保存在一个文件夹中,也就是生成的时候所有依赖文件都会被找出来拷贝到一个文件夹里面,有一个比较小的exe可以启动程序。
-F生成的文件只有一个exe,所有的文件通过压缩等操作,写道一个exe文件里面,这样生成的文件数量少(只有一个),内存占用小。但是有一个严重问题,像我写道程序是UI程序,里面的外部的dll就比较多,程序在开启的时候会格外的慢,有一种说法是,虽然程序只有一个exe但是运行的时候还是会先把这些依赖解析出来,然后启动程序,所以降低了程序的启动速度。所以这个方面还需要优化一下,我后面再补这个问题怎么解决吧,目前就这样用,自己考虑取舍,选择合适的打包方式。
然后
–specpath DIR 一般这个就不改了,就放在自己程序目录就可以了。
-n NAME这个一般我会改一下,比如你开始写的程序就直接把启动的文件命名为main,那编译出来就是main.exe,这个时候根据具体功能去修改叫想叫的名字就很好,比如 -n Hello.

关闭程序运行的黑窗

 -w, --windowed, --noconsole
                        Windows and Mac OS X: do not provide a console window for standard i/o. On Mac OS this also triggers building a Mac OS .app bundle. On Windows this option is automatically set if the first script is a '.pyw' file. This option is ignored on *NIX systems.

使用-w表示这个程序是一个窗口程序,不需要控制台,这个参数还有–windowed, --noconsole两种表达方式,都是为了说明这个意思。

补充说明

修改文件运行的图标

-i <FILE.ico or FILE.exe,ID or FILE.icns or Image or “NONE”>, --icon <FILE.ico or FILE.exe,ID or FILE.icns or Image or “NONE”>
FILE.ico: apply the icon to a Windows executable. FILE.exe,ID: extract the icon with ID from an exe. FILE.icns: apply the icon to the .app bundle on Mac OS. If an image file is entered that isn’t in the platform format (ico on Windows, icns on Mac), PyInstaller tries to use Pillow to
translate the icon into the correct format (if Pillow is installed). Use “NONE” to not apply any icon, thereby making the OS show some default (default: apply PyInstaller’s icon)
通过添加-i 和指定的ico文件就可以让你的程序显示你想显示的图标,这个图标在windows程序上会有些坑,如果遇到这些问题,可以尝试看我写的另一篇关于图标的文章,参考制作ico。
除了这个之外,程序还可以通过 FILE.exe,ID,也就是程序里面资源的ID显示图标,这个方法我还没试过,有兴趣可以尝试,我是觉得没有第一种方式好用,有意思的是,接口里面说,如果安装了Pillow ,还会尝试把不同平台的图标转到想要使用的平台。

修改程序的信息

help信息里面还有一些没有详细解释的选项也值得我们注意的,其中[–version-file FILE]可以修改文件的版本信息。通过添加下面的代码启动修改版本信息,这里面信息很多,所以写在一个文件里面

--version-file=Version.txt

这里我修改程序的公司,程序名称,程序生成的exe,程序的描述和程序的版本号,这些信息都可以在这修改,其中我们最关心的可能是版本号了。版本号修改这几个字段
filevers
prodvers
StringStruct(u’FileVersion’, u’0.1.0.0 (win7sp1_rtm.101119-1850)‘),
StringStruct(u’ProductVersion’, u’0.1.0.0’)])

# UTF-8
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
    # Set not needed items to zero 0.
    filevers=(0, 1, 0, 0),
    prodvers=(0, 1, 0, 0),
    # Contains a bitmask that specifies the valid bits 'flags'r
    mask=0x3f,
    # Contains a bitmask that specifies the Boolean attributes of the file.
    flags=0x0,
    # The operating system for which this file was designed.
    # 0x4 - NT and there is no need to change it.
    OS=0x40004,
    # The general type of file.
    # 0x1 - the file is an application.
    fileType=0x2,
    # The function of the file.
    # 0x0 - the function is not defined for this fileType
    subtype=0x0,
    # Creation date and time stamp.
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'040904B0',
        [StringStruct(u'CompanyName', u'公司名称'),
        StringStruct(u'FileDescription', u'软件名称'),
        StringStruct(u'FileVersion', u'0.1.0.0 (win7sp1_rtm.101119-1850)'),
        StringStruct(u'InternalName', u'软件名.exe'),
        StringStruct(u'LegalCopyright', u'© 我的公司. All rights reserved.'),
        StringStruct(u'OriginalFilename', u'软件名.exe'),
        StringStruct(u'ProductName', u'软件名字描述'),
        StringStruct(u'ProductVersion', u'0.1.0.0')])
      ]),
    VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
  ]
)

引入版本报错

还有的时候我们的某些版本,在程序里面添加了import一些模块,编辑器运行都是正常的,但是打包出去说缺少模块,可以通过–hidden-import隐藏这些模块导入,重新打包程序就可以正常运行了。比如我的程序有pyqt5,下面这句就很有效。

--hidden-import PyQt5

结语

打包参数很多,还需实际使用不断摸索。欢迎提问,共同成长。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值