PyInstaller是一个能将Python程序转换成单个可执行文件的程序, 操作系统支持Windows, Linux, Mac OS X, Solaris和AIX。并且很多包都支持开箱即用,不依赖环境。

环境为windows7操作系统,python2.7.8 virtual environment

官网:https://github.com/pyinstaller/pyinstaller

详细步骤:

1. win7下面先安装这个依赖:pywin32,下载下来后切换到venv2.7,然后使用easy_install xxx.exe安装

2. pip安装PyInstaller:

pip install pyinstaller

3. 打包过程中可能会出现msvcp90.dll找不到的问题, 去http://cn.dll-files.com/msvcp90.dll.html下载第三个zip文件, 解压后放到C:\Windows\System32,如果是64位的还要放到C:\Windows\SysWOW64目录下。

4. 再次运行报MSVCR90.dll找不到,同理去http://cn.dll-files.com/MSVCR90.dll.html下载MSVCR90.dll, 放到C:\Windows\System32和C:\Windows\SysWOW64中。

5. 将你的整个程序先复制到某个临时文件夹下面,比如D:\tmp\core-wxpython,此目录下有个main.py是执行入口

6. 执行build命令,并添加必要的搜索路径,外加执行文件的图标:

cd D:\tmp\core-wxpython
pyinstaller -F -w -i d:\tmp\main.ico main.py

如果还想添加自定义的依赖库,就要加上-p参数:

pyinstaller -F -w -p D:\tmp\core-python\libs -i d:\tmp\main.ico main.py

参数说明:

-F 表示生成单个可执行文件
-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!
-p 表示你自己自定义需要加载的类路径,一般情况下用不到
-i 表示可执行文件的图标

注意的事情

1). 检查生成的\XXX\build\pyi.win32\XXX\warnXXX.txt(XXX是你的项目名)中, 是否缺少了必要的模块。如果有缺少的,那么去如上所述,添加必要的搜素路径, 使得pyinstaller在运行时,可以找到对应的模块并集成进来。

2). 此处我这里没有UPX,暂时没去折腾。估计是用UPX去压缩,压缩后所生成的exe文件的大小,会小得多。

7. 如果发现报错:pywintypes.error: (193, ‘LoadLibraryEx’… ) 原因是添加图标后缀必须是xxx.ico才行,重新去网上下载一个ico格式的图片,再次运行就好了。

8. 我测试了一个使用wxpython写的gui程序,源码里面引用了一张图片, 使用wx.Image(os.path.abspath(file/me.jpg), wx.BITMAP_TYPE_JPEG)来加载, 然后打包成exe后发现找不到图片了,报错。

解决办法:

第一步,在程序中将资源文件都放到一个单独的文件夹中,比如项目根目录下面的resources

第二步,修改程序中引用这些资源文件比如图片的代码:

1
2
3
4
5
6
7
def resource_path(relative_path):
"""定义一个读取相对路径的函数"""
if hasattr(sys, "_MEIPASS"):
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)

然后每次在获取图片的时候,这么引用它的目录:

1
img = wx.Image(resource_path('resources/me.jpg'), wx.BITMAP_TYPE_JPEG)

第三步,先运行第6步生成一个main.spec文件

第四步,修改main.spec文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# -*- mode: python -*-
a = Analysis(['main.py'],
pathex=['d:\\tmp\\core-wxpython'],
hiddenimports=[],
hookspath=None,
runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[('\\resources\\me.jpg','D:\\tmp\\core-wxpython\\resources\\me.jpg','DATA')],
name='main.exe',
debug=False,
strip=None,
upx=True,
console=True , icon='d:\\tmp\\main.ico')

注意:我在a.datas下面添加了那行配置,具体的路径自己去修改下。

上面是添加单个文件,如果有多个文件,可以一个个的添加。不过如果文件多了话,那么就使用下面的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# -*- mode: python -*-
a = Analysis(['main.py'],
pathex=['d:\\tmp\\core-wxpython'],
hiddenimports=[],
hookspath=None,
runtime_hooks=None) def extra_datas(mydir):
def rec_glob(p, files):
import os
import glob
for d in glob.glob(p):
if os.path.isfile(d):
files.append(d)
rec_glob("%s/*" % d, files)
files = []
rec_glob("%s/*" % mydir, files)
extra_datas = []
for f in files:
extra_datas.append((f, f, 'DATA')) return extra_datas # append the 'resources' dir
a.datas += extra_datas('resources') pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='main.exe',
debug=False,
strip=None,
upx=True,
console=True , icon='d:\\tmp\\main.ico')

它会把某个指定的文件下的所有文件递归的添加到最终的包中。省去很多事情!

第五步,执行:pyinstaller D:\tmp\core-wxpython\main.spec

然后就大功告成了!!!在dist目录下面有个main.exe单独的可执行文件,打开它吧。^_^

如果在执行过程中出错,或者双击打开没任何反应。 可以先去掉-w参数后,在控制台窗口打开这个可执行文件,会输出详细出错信息去调试。

其他问题记录

1. 找不到pkg_resources

ImportError: No module named pkg_resources

解决办法是在安装pycrypto之前,先安装distribute库

1
curl https://svn.apache.org/repos/asf/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py | python

然后再安装windows下面对应的pycrypto库

# http://www.voidspace.org.uk/python/modules.shtml#pycrypto
easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win-amd64-py2.7.exe

2. 打包时加上-w选项去掉console时出错

不要在程序中使用任何print语句,或者是你将stdout重定向到一个日志、文件或任何其他非控制台地方。

最好的方法是利用日志功能,将输出定向到日志文件中去,在main函数开头添加如下代码:

1
2
3
4
5
import logging
import tempfile
logging.basicConfig(level=logging.INFO,
filename=tempfile.TemporaryFile().name,
format='%(asctime)s %(message)s')

用到logging的时候,需要配置日志到文件中,而不是console:

1
2
import logging
_LOGGING = logging.getLogger(__file__)

3. pyinstaller用one file方式打包的程式如果有用到subprocess.Popen會有問題

问题参考:http://www.pyinstaller.org/ticket/597

最後找到的方法是 http://code.activestate.com/recipes/578300-python-subprocess-hide-console-on-windows/

建立一個隐藏窗口,就正常了~

最后用pyinstaller設one folder & no console打包都不跳出小窗口了

解决办法就是自定义一个subprocess_call函数来代替subprocess的call调用,不适用Popen了:

1
2
3
4
5
6
7
8
9
10
11
def subprocess_call(*args, **kwargs):
# also works for Popen. It creates a new *hidden* window,
# so it will work in frozen apps (.exe).
if IS_WIN32:
_LOGGING.info('subprocess_call==IS_WIN32')
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
kwargs['startupinfo'] = startupinfo
retcode = subprocess.call(*args, **kwargs)
return retcode

调用方法:

1
exresult = subprocess_call(exe_command, shell=True)

这个方法会等命令执行完成,返回值为0表示正常结束!

4. 打包后不能放到中文路径下执行 解决办法是下载安装PyInstaller的中文支持库,安装后再重新执行pyinstaller打包命令:

1
2
3
git clone https://github.com/dkw72n/pyinstaller.git
python setup.py install
pyinstaller -F -w -i d:\tmp\main.ico main.py

【Python开发】PyInstaller打包Python程序的更多相关文章

  1. PyInstaller 打包 python程序成exe

    pychaim下PyInstaller 打包 python程序 主题是使用PyInstaller 打包python时遇到一些问题以及解决方案,其中将要打包的程序是用tensorflow做的LSTM算法 ...

  2. “failed to excute script xxx” PyInstaller 打包python程序为exe文件过程错误

    在使用PyInstaller打包python程序,打包命令为: pyinstaller -F -w -i manage.ico yourpyfile.py 顺便说一下几个参数的作用 -F:是直接生成单 ...

  3. PyInstaller打包python脚本的一些心得

    PyInstaller打包python脚本的一些心得 因为在公司经常要帮同事做一个从excel表格中提取出需要的内容的重复工作,比较繁琐还容易出错:于是就想着要写个程序,但是同事又不可能在电脑上也装上 ...

  4. pyinstaller打包.py程序为.exe操作指南

    pyinstaller打包.py程序为.exe操作指南 20190526内容纲要: 1.pyinstaller安装 2.程序封装 3.可执行程序 0 前言 今天第一次试试将一个py程序封装成一个.ex ...

  5. pyinstaller打包exe程序各种坑!!!

    pyinstaller打包python成exe可执行程序,各种报错,各种坑,在次记录下 一.pyinstaller打包报错for real_module_name, six_moduleAttribu ...

  6. visual studio 2015 搭建python开发环境,python入门到精通[三]

    在上一篇博客Windows搭建python开发环境,python入门到精通[一]很多园友提到希望使用visual studio 2013/visual studio 2015 python做demo, ...

  7. 使用pyinstaller打包.py程序

    使用pyinstaller打包.py程序 例如打包D:/Desktop 目录下的 filename.py 文件 打开 cmd 将目录切换至 D:/Desktop 输入命令 pyinstaller -F ...

  8. [python学习笔记] pyinstaller打包pyqt5程序无法运行

    问题 pyinstaller打包的pyqt5程序在部分电脑上会失败.用户截图提示下边错误日志 无法定位程序输入点 ucrtbase.terminate 于动态链接库 api-ms-win-crt-ru ...

  9. 【Python】解决使用pyinstaller打包Tkinker程序报错问题

    问题描述 使用pyinstaller打包使用Tkinter编写的控制台程序,出现报错 15793 INFO: Adding Microsoft.Windows.Common-Controls to d ...

随机推荐

  1. collections.defaultdict()

    https://www.cnblogs.com/herbert/archive/2013/01/09/2852843.html >>> import collections > ...

  2. 含-SH的ACE抑制药的青霉胺样反应

    关于 含-SH的血管紧张素转化酶(ACE)抑制药如卡托普利具有青霉胺样反应.而依那普利则不含-SH. 青霉胺样反应 青霉胺样反应,指应用含-SH的ACE抑制药产生的皮疹.嗜酸性粒细胞(E)增多.味觉异 ...

  3. Tips on Blind Source Separation

    盲源分离是指在不知道源信号和信道传输参数的情况下,根据输入信号的统计特性,仅由观测信号恢复出源信号各个独立成分的过程.盲源分离研究的信号模型主要有三种:线性混合模型.卷积混合模型和非线性混合模型. 1 ...

  4. LeetCode 358. Rearrange String k Distance Apart

    原题链接在这里:https://leetcode.com/problems/rearrange-string-k-distance-apart/description/ 题目: Given a non ...

  5. Codevs 1305 Freda的道路(矩阵乘法 DP优化)

    1305 Freda的道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description Freda要到Rainbow的城堡去玩了.我们可以认 ...

  6. 复旦高等代数 I(16级)每周一题

    每周一题的说明 一.本学期高代I的每周一题面向16级的同学,将定期更新(一般每周的周末公布下一周的题目); 二.欢迎16级的同学通过微信或书面方式提供解答图片或纸质文件给我,优秀的解答可以分享给大家: ...

  7. GoCN每日新闻(2019-10-06)

    GoCN每日新闻(2019-10-06) 国庆专辑:GopherChina祝大家国庆节快乐 GoCN每日新闻(2019-10-06) 1. Go 1.14 有什么新变化 http://docs.goo ...

  8. 随机采样方法整理与讲解(Acceptance-Rejection、MCMC、Gibbs Sampling等)

    本文是对参考资料中多篇关于sampling的内容进行总结+搬运,方便以后自己翻阅.其实参考资料中的资料写的比我好,大家可以看一下!好东西多分享!PRML的第11章也是sampling,有时间后面写到P ...

  9. 关于Java正则和转义中\\和\\\\的理解

    定义 一个转义字符的目的是开始一个字符序列,使得转义字符开头的该字符序列具有不同于该字符序列单独出现时的语义. 转义就是指转换该字符的原本意义,从而变成另外的意义. \作为Java的转义字符 1.在j ...

  10. 2015-2016-2《Java程序设计》团队博客2

     简易画图板介绍 一.功能结构图 二.主类设计 1.总体设计:在设计简易画图板时,根据程序功能的分类,包含了十二个文件,包括SimpleDraw.java,MenuContainer.java,Dra ...