Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题


Posted in Python onJuly 15, 2019

1 调试过程

用Python3.6+Sciter+PyCharm写了一个py测试脚本helloworld.py,该脚本中只含有一条语句“import sciter”。在PyCharm中运行之,未报错。

#helloworld.py
import sciter

然后将该脚本用PyInstaller打包成exe文件,打包程序pack.py如下:

#pack.py
from PyInstaller.__main__ import run
if __name__ == '__main__':
  opts = [
      # 字符串前加“r”,防止字符转义
      # r'--hidden-import=py4j.java_collections',\
      # 要打包的Python文件
      r'D:\work\python\my_editor\helloworld\helloworld.py',\
      # -F, ?onefile 打包一个单个文件,如果你的代码都写在一个.py文件的话,可以用这个,如果是多个.py文件就别用
      # '-F',\
      # -w:制作窗口程序,与之相对的-c意味制作命令行程序(默认)。--distpath指定打包的目的地路径
      r'-w','--distpath=D:\work\python\my_editor\helloworld\dist',\
      # --workpath 指定工作路径
      r'--workpath=D:\work\python\my_editor\helloworld\out',\
      # --specpath指定.spec文件保存路径
      r'--specpath=D:\work\python\my_editor\helloworld\out',\
      # --icon 指定exe文件的图标
      r'--icon=D:\work\python\my_editor\ico\text.ico',\
      # --upx-dir 使用upx压缩
      r'--upx-dir','upx393w',\
      # --add-data 指定要包含的资源文件。
      # “C:\\Windows\\System32\\sciter.dll”为资源文件原本所在路径(source)。
      # “.”为相对于exe文件的路径(destination),在这里“.”为同一目录的意思。
      # source路径与destination路径以英文状态下分号“;”隔开。
      # r'--add-data', 'C:\\Windows\\System32\\sciter.dll;.', \
      # r'--add-data', 'D:\\work\\python\\my_editor\\helloworld\\pages\\word.html;pages'
      ]
  run(opts)

打包过程未报错,但打包后执行exe文件就出现问题了,如下图,报错“Failed to execute script helloworld”。

 Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题

就这么一句话,没有其他任何的报错信息,很令人恼火。后来查了资料,发现在打包时,可以指定exe以命令行模式执行,就能看到报错信息,而非以当前的窗口模式执行。即将上述pack.py脚本中的opts选项列表里的“-w”改为“-c”。

再次打包执行exe文件,发现了弹出了一个含有报错信息的窗口。但是窗口一闪即逝,根本看不清里面的报错信息。这是因为程序抛出异常退出了;即使不抛出异常,窗口也会因程序执行完成而消失。于是将主程序helloworld.py的代码改为如下:

#helloworld.py
import traceback
#加上try-except语句,是为了防止程序在出现异常时奔溃退出。
try:
  import sciter
except Exception as e:
  #打印异常栈轨迹。
  traceback.print_exc()
  #使程序阻塞,防止程序执行完毕退出。
  a = input()

再次打包执行exe文件,能看到报错信息了,如下图。其中的核心信息是“ImportError: C:\Windows\System32\sciter.dll was not found in PATH”,即缺少sciter.dll文件。

Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题

这就很奇怪了,在PyCharm中运行时没报这个错啊!查看PyInstaller官网,得知PyInstaller打包后的exe程序不能自动识别资源文件(如dll、html、png等文件)的路径,需要在spec文件中指定datas选项。比如下面的helloworld.spec片段,添加了sciter.dll文件到与exe文件同级的目录(.)中;添加了word.html到比exe文件所在目录更深一层的目录(pages)中(若是只报错缺少dll文件,可不指定html文件)。

#helloworld.spec片段

a = Analysis(['D:\\work\\python\\my_editor\\helloworld\\helloworld.py'],
       pathex=['D:\\work\\python\\my_editor\\helloworld\\out'],
       binaries=[],
       datas=[('C:\\Windows\\System32\\sciter.dll', '.'), ('D:\\work\\python\\my_editor\\helloworld\\pages\\word.html', 'pages')],
       hiddenimports=[],
       hookspath=[],
       runtime_hooks=[],
       excludes=[],
       win_no_prefer_redirects=False,
       win_private_assemblies=False,
       cipher=block_cipher,
       noarchive=False)

但每次执行完打包程序后,还要手动修改spec文件,很是麻烦。通过调试PyInstaller源代码,找到了另一种方法,即在pack.py打包程序中的opts选项列表里加上两个“--add-data选项”,如下:

#helloworld.py片段

opts = [
    """
    其他选项与上面的helloworld.py同,此处省略。
    """
    # --add-data 指定要包含的资源文件。
    # “C:\\Windows\\System32\\sciter.dll”为资源文件原本所在路径(source)。
    # “.”为相对于exe文件的路径(destination),在这里“.”为同一目录的意思。
    # source路径与destination路径以英文状态下分号“;”隔开。
    r'--add-data', 'C:\\Windows\\System32\\sciter.dll;.', \
    r'--add-data', 'D:\\work\\python\\my_editor\\helloworld\\pages\\word.html;pages'
    ]

再次打包运行exe文件,执行成功!

2 要点总结

(1)调试打包时,指定PyInstaller打包程序参数为“-c”(命令行模式),方便阅读报错信息。等到调试完成正式上线后再改为“-w”。

(2)通过捕捉异常和使程序阻塞,防止程序过早退出,以便于看清楚报错信息。

(3)PyInstaller打包后的exe程序不能自动识别资源文件(如dll、html、png等文件)的路径,需要在spec文件中指定datas选项,或者在PyInstaller打包程序参数中指定一个或多个“--add-data”选项。

总结

以上所述是小编给大家介绍的Python3+PyInstall+Sciter解决报错缺少dll、html等文件问题 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
python正则表达式修复网站文章字体不统一的解决方法
Feb 21 Python
Python实现竖排打印传单手机号码易撕条
Mar 16 Python
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
Sep 28 Python
关于django 数据库迁移(migrate)应该知道的一些事
May 27 Python
Python构建图像分类识别器的方法
Jan 12 Python
带你认识Django
Jan 15 Python
详解Django CAS 解决方案
Oct 30 Python
python如何使用jt400.jar包代码实例
Dec 20 Python
pytorch查看torch.Tensor和model是否在CUDA上的实例
Jan 03 Python
Tensorflow的常用矩阵生成方式
Jan 04 Python
Python使用pyexecjs代码案例解析
Jul 13 Python
Python在后台自动解压各种压缩文件的实现方法
Nov 10 Python
关于python中密码加盐的学习体会小结
Jul 15 #Python
Python替换月份为英文缩写的实现方法
Jul 15 #Python
使用python爬取抖音视频列表信息
Jul 15 #Python
python过滤中英文标点符号的实例代码
Jul 15 #Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
Jul 15 #Python
python 判断字符串中是否含有汉字或非汉字的实例
Jul 15 #Python
如何利用Python模拟GitHub登录详解
Jul 15 #Python
You might like
php中json_encode不兼容JSON_UNESCAPED_UNICODE的解决方案
2016/05/31 PHP
Laravel框架中自定义模板指令总结
2017/12/17 PHP
在图片上显示左右箭头类似翻页的代码
2013/03/04 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
2015/08/03 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
JavaScript提升性能的常用技巧总结【经典】
2016/06/20 Javascript
JS实现数组按升序及降序排列的方法
2017/04/26 Javascript
Javascript实现一个简单的输入关键字添加标签效果实例
2017/06/01 Javascript
Vue如何实现组件的源码解析
2017/06/08 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
Vue将页面导出为图片或者PDF
2020/08/17 Javascript
nuxt 实现在其它js文件中使用store的方式
2020/11/05 Javascript
详解Typescript里的This的使用方法
2021/01/08 Javascript
[04:29]2016国际邀请赛中国区预选赛Ehome战队教练采访
2016/06/27 DOTA
Python3实现连接SQLite数据库的方法
2014/08/23 Python
python求crc32值的方法
2014/10/05 Python
python基于Tkinter库实现简单文本编辑器实例
2015/05/05 Python
Python批量修改文本文件内容的方法
2016/04/29 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
python3+PyQt5 使用三种不同的简便项窗口部件显示数据的方法
2019/06/17 Python
Python缓存技术实现过程详解
2019/09/25 Python
Pyinstaller加密打包应用的示例代码
2020/06/11 Python
python实现单机五子棋
2020/08/28 Python
Python装饰器如何实现修复过程解析
2020/09/05 Python
美国时尚配饰品牌:Dooney & Bourke
2017/11/14 全球购物
Aosom西班牙:家具在线商店
2020/06/11 全球购物
广州足迹信息技术有限公司Java软件工程师试题
2014/02/15 面试题
单位工作证明
2014/10/07 职场文书
写给导师的自荐信
2015/03/06 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
六一儿童节园长致辞
2015/07/31 职场文书
SQLServer RANK() 排名函数的使用
2022/03/23 SQL Server
Mysql将字符串按照指定字符分割的正确方法
2022/05/30 MySQL
springboot读取resources下文件的方式详解
2022/06/21 Java/Android