如何调试一个PyInstaller构建失败的程序?

12

我之前只使用过一次PyInstaller,用wxPython很容易上手。但现在我正在尝试构建另一个项目。该项目在命令行下运行良好。然而,在构建完成后,它从未启动主窗口(wxPython)。

我已经在构建规范中将debug和console标志设置为True。根据PyInstaller手册的规定,我还添加了verbose选项([('v', '', 'OPTION')])。以下是构建规范:

# -*- mode: python -*-
# basedir = os.path.realpath(os.path.dirname(__file__))
basedir = os.getcwd()
# Build the icons toc. icons_toc = [] for dir in os.walk(os.path.join(basedir, 'icons')): for icon in dir[2]: icons_toc.append( ( os.path.join('icons', icon), os.path.join(dir[0], icon), 'DATA', ) )
a = Analysis( ['application.py'], pathex=['.', './lib', '../broadpy/lib', '../broadpy/vendor'], hiddenimports=[], hookspath=None ) a.datas += icons_toc pyz = PYZ(a.pure)
exe = EXE( pyz, a.scripts + [('v', '', 'OPTION')], a.binaries, a.zipfiles, a.datas, name=os.path.join( 'dist', 'Address cleaner.exe' ), debug=True, strip=None, upx=True, console=True )
app = BUNDLE( exe, name=os.path.join('dist', 'Address cleaner.app') )

现在,当我运行构建的可执行文件时,我得到了以下输出:

C:\Users\tomas\Dropbox\Broadnet\address_cleaner>"C:\Users\tomas\Dropbox\Broadnet\address_cleaner\dist\Address cleaner.exe"
_MEIPASS2 is NULL
archivename is C:\Users\tomas\Dropbox\Broadnet\address_cleaner\dist\Address cleaner.exe
Extracting binaries
Executing self as child with Setting up to run child
Creating child process
Waiting for child process to finish...
_MEIPASS2 is C:/Users/tomas/AppData/Local/Temp/_MEI30762/
archivename为C:\Users\tomas\Dropbox\Broadnet\address_cleaner\dist\Address cleaner.exe。已在子进程中运行!manifestpath:C:/Users/tomas/AppData/Local/Temp/_MEI30762/Address cleaner.exe.manifest。创建激活上下文,激活激活上下文。C:/Users/tomas/AppData/Local/Temp/_MEI30762/python27.dll正在操作环境。PYTHONPATH=C:/Users/tomas/AppData/Local/Temp/_MEI30762;C:/Users/tomas/Dropbox/Broadnet/address_cleaner/dist,PYTHONHOME=C:/Users/tomas/AppData/Local/Temp/_MEI30762/。#安装zipimport钩子,导入CArchive模块,解压缩iu,导入imp、nt和struct模块。正在安装导入钩子,out00-PYZ.pyz正在运行脚本,导入zlib、errno、_weakref、_codecs、_sre、_collections、operator、itertools、_bisect、_heapq、thread、math、binascii和_random模块,导入cStringIO模块,最近的一次调用引发了Traceback错误,文件路径为C:\Users\tomas\Downloads\pyinstaller-2.0\PyInstaller\loader\iu.py,行数为65,在C:\Users\tomas\Downloads\pyinstaller-2.0\PyInstaller\loader\iu.py中的importHook函数中出现问题,在C:\Users\tomas\Downloads\pyinstaller-2.0\PyInstaller\loader\iu.py中的doimport函数中出现问题,在C:\Users\tomas\Dropbox\Broadnet\address_cleaner\build\pyi.win32\buildspec\out00-PYZ.pyz的win32com文件中出现问题。文件“C:\Users\tomas\Downloads\pyinstaller-2.0\PyInstaller\loader\iu.py”中第386行发生错误,导致无法找到指定模块。这是由于在第105行的getmod函数加载DLL时失败,最终导致RC为-1的错误。程序结束前执行了一系列的清理操作。# cleanup[1]线程 # cleanup[1]关键词 # cleanup[1]信号 # cleanup[1]随机数 # cleanup[1]itertools模块 # cleanup[1]encodings.aliases模块 # cleanup[1]异常 # cleanup[1]堆队列模块 # cleanup[1]sre_compile模块 # cleanup[1]_sre模块 # cleanup[1]_random模块 # cleanup[1]hashlib模块 # cleanup[1]bisect模块 # cleanup[1]sre_parse模块 # cleanup[1]_hashlib模块 # cleanup[2]copy_reg模块 # cleanup[2]os.path模块 # cleanup[2]归档模块 # cleanup[2]struct模块 # cleanup[2]errno模块 # cleanup[2]imp模块 # cleanup[2]_abcoll模块 # cleanup[2]ntpath模块 # cleanup[2]nt模块 # cleanup[2]genericpath模块 # cleanup[2]stat模块 # cleanup[2]zipimport模块 # cleanup[2]warnings模块 # cleanup[2]UserDict模块 # cleanup[2]types模块 # cleanup[2]zlib模块 # cleanup[2]linecache模块 # cleanup[2]os模块 # cleanup[2]marshal模块 # cleanup sys模块 # cleanup __builtin__模块 # cleanup ints: 41未释放的整数 # cleanup floats: 31未释放的浮点数 返回到上级... 释放C:\Users\tomas\Dropbox\Broadnet\address_cleaner\dist\Address cleaner.exe的状态

现在我看到iu.py中产生了一个异常,但仍然不知道为什么会这样。我还发现即使我删除了Downloads/py-installer文件夹,我的应用程序仍然会运行该文件夹中的python文件,这让我感到非常神秘。

综上所述 - 我需要采取哪些步骤才能确定应用程序在启动时崩溃的原因?


我在Windows 8上使用Python 2.7.3和PyInstaller 2.0。这些事实的任何一个单独都不会导致此错误,因为我成功地构建了另一个项目。

2个回答

7

有时,Pyinstaller需要在.spec文件中显式引用才能正确打包依赖项

更多信息,请参见确保正确的导入语句,以使pyinstaller识别它们

例如,如果从Python模块之外导入(例如从jar或C++文件中),则很容易忽略关键的依赖项(而pyinstaller将不会读取它们)。

Dependency Walker可以成为您系统地跟踪缺少DLL的第一道防线。只需下载并加载您的exe或相关dll,查看缺少哪些依赖项。然后,就是一个猫捉老鼠的游戏,手动将它们添加到与.exe相同的目录中(假设您正在一个目录中进行打包)。

顺便说一下,对于pyinstaller 2.1(python 2.7.6),我修改了pyi_importers.py文件,至少尝试在导入时打印哪个模块出了问题:

# line 409 of Pyinstaller.loader.pyi_importers.py
try: module = imp.load_module(fullname, fp, filename, self._c_ext_tuple)
except Exception as e:
    print fullname # at least tells you what module couldn't be imported
    raise e

了解问题出现的位置后,您可以使用依赖项查找程序定位缺失的 DLL 并排除问题。


解决我的问题的方法是在WinXP上重新编译pyd模块(特别是pcapy),并将其复制到我的Windows 7 python安装中。现在,我在Windows 7上构建的pyinstaller exe文件也可以在Windows XP和Windows 7上运行。 - SW_user2953243
你或许能够帮助解决我的问题 - ballade4op52

2

我知道这个回答并没有解答如何调试此类问题,所以我不会将其标记为正确的,但我已经成功构建了应用程序,并且我想分享一下我的做法。我做了三件事,每一件事可能是错误的原因,但我们永远不会知道:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接