【问题标题】:Executable made with pyInstaller/UPX experiences QtCore4.dll error使用 pyInstaller/UPX 制作的可执行文件遇到 QtCore4.dll 错误
【发布时间】:2017-01-31 12:57:44
【问题描述】:

我用pyInstaller 编译的python 程序结果超过400 MB。该程序的 GUI 基于htmlPY,它是“PySide 的 QtWebKit 库的包装器”。该程序的大型部分是由于它使用了 numpy、scipy 和 nltk,部分原因是由于图形库。

为了最小化程序的大小,我安装了UPX。这将程序的大小减小到略高于 100MB,虽然很大,但可以接受。

第一个问题是pyInstaller没有检测到htmlPy,也没有把它包含在编译的程序中。这可以通过将我的 Python 安装中的 htmlPy 模块复制到 pyInstaller 创建的“dist”目录中来解决。完成此操作后,未使用 UPX 编译的程序版本运行良好。

将 htmlPy 添加到“dist”目录后,运行可执行文件会在创建 GUI 时使程序崩溃。我不确定这是否是由于 UPX 和 QT 之间或 UPX、QT 和 htmlPy 之间的交互问题造成的。 Windows“问题签名”如下:

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: main.exe
  Application Version:  0.0.0.0
  Application Timestamp:    00000000
  Fault Module Name:    QtCore4.dll
  Fault Module Version: 4.8.7.0
  Fault Module Timestamp:   561e435a
  Exception Code:   c0000005
  Exception Offset: 000000000010883a

关于这里发生了什么以及如何解决它的任何想法?

编辑:

这些是我的 .spec 文件的内容:

# -*- mode: python -*-

block_cipher = None

added_files = [
     ( 'htmlPy/binder.js', 'htmlPy' ),
     ( 'templates/*', 'templates' ),
   ]
a = Analysis(['main.py'],
             pathex=['C:\\..\\My_App'],
             binaries=None,
             datas=added_files,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=['rthook_pyqt4.py'],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='My_App',
          debug=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='My_App')

这些是 rthook_pyqt4.py 的内容:

import sip

sip.setapi(u'QDate', 2)
sip.setapi(u'QDateTime', 2)
sip.setapi(u'QString', 2)
sip.setapi(u'QTextStream', 2)
sip.setapi(u'QTime', 2)
sip.setapi(u'QUrl', 2)
sip.setapi(u'QVariant', 2)

编辑 2:

这里是一些初始化代码(standard htmlPy fare):

app.static_path = path.join(BASE_DIR, "static/")
print "Step 1"
app.template_path = path.join(BASE_DIR, "templates/")
print "Step 2"
app.template = ("index.html", {"username": "htmlPy_user"})
print "Step 3"
...

程序在进入第 3 步之前崩溃。

【问题讨论】:

  • 你能告诉我们你的setoop.py吗?如何将您的模块添加为导入或附加?
  • @dsgdfg 抱歉 - 什么是“setoop.py”,您指的是哪个导入的模块?
  • setup.py 代码,如何添加库?
  • 虽然有时可以,但是将模块复制到 pyinstaller 文件夹中并不是一个好主意。尝试使用--hidden-import 选项添加缺少的模块,看看是否还有问题。
  • 感谢大家的支持。我想奖励赏金积分(还有 23 小时可以这样做),但我们还没有任何答案表明可能的诊断措施,也没有可能的解决方案。我想我会尝试与 UPX 和 pyInstaller 人员取得联系,看看他们是否可以提供任何建议。

标签: python qt pyside pyinstaller upx


【解决方案1】:

您的两大担忧涉及:

  1. 正确性 - 使用 UPX 的应用无法运行
  2. 性能 - 400 MiB “太大”,而 100 MiB 可让您处理更多用户

如果应用程序更小,它可能对更多人更有用,但如果它无法运行,它对任何人都没有用。您怀疑 UPX 改进了关注点 2,但它的交互影响了关注点 1。

构建一个简单的 HelloWorld 应用程序会很有趣,使用 pyInstaller + UPX 对其进行打包,并继续使用其他依赖项(如 Qt)对其进行修饰,直到您看到它以类似于当前损坏的方式损坏。

放弃 UPX 转而采用其他方法(包括 NSIS)可能会更有成效。您可以使用 strace() 之类的工具来监控在系统测试运行期间实际使用了哪些分布式文件,并在打包期间修剪未使用的文件。通过FUSE 代理请求会产生类似的信息。您可以列出已发布应用的依赖项,并依靠 pip 或 conda 并行下载依赖项,如果“已用安装时间”确实是您希望将 400 缩小到 100 MiB 的原因。

【讨论】:

    猜你喜欢
    • 2020-12-21
    • 2020-02-04
    • 2019-01-21
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多