我想为我制作的小项目制作一个exe文件。但是它根本没有运行。
我尝试了PyInstaller does not include dependency file 但是它会抛出
Traceback (most recent call last):
File "C:\Program Files\Python37\Scripts\pyinstaller-script.py", line 11, in <module>
load_entry_point('PyInstaller==3.4', 'console_scripts', 'pyinstaller')()
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\__main__.py", line 111, in run
run_build(pyi_config, spec_file, **vars(args))
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\__main__.py", line 63, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\building\build_main.py", line 838, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\building\build_main.py", line 784, in build
exec(text, spec_namespace)
File "<string>", line 8, in <module>
IndexError: list index out of range
如果我只是执行“ pyinstaller --clean --onefile Start.py”,则会显示:
File "Start.py", line 5, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "Modules\HTMLToPDF.py", line 1, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\weasyprint\__init__.py", line 20, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\cssselect2\__init__.py", line 20, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\cssselect2\compiler.py", line 7, in <module>
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
File "C:\Program Files\Python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 627, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\tinycss2\__init__.py", line 10, in <module>
File "pathlib.py", line 1189, in read_text
File "pathlib.py", line 1176, in open
File "pathlib.py", line 1030, in _opener
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Daniel\\AppData\\Local\\Temp\\_MEI100202\\tinycss2\\VERSION'
[12796] Failed to execute script Start
我该如何解决?我只想要一种分发代码的好方法。
答案 0 :(得分:0)
老实说,您的项目很大,并且其中包含许多复杂的库,PyInstaller不能单独处理所有这些库。在这里,我告诉您一些解决方案。
首先,当PyInstaller抱怨缺少文件时,这意味着您需要自己提供该文件。例如,在您的错误中,它抱怨VERSION
中存在的C:\\Users\\Daniel\\AppData\\Local\\Temp\\_MEI100202\\tinycss2
文件不是。因此,您需要自己将其添加为数据文件。
第二,如果需要引入一些外部依赖项,例如cairo
,则需要使用Tree
函数引入整个依赖关系目录。您可以找到有关here的更多信息。
我构建了项目并修复了一些依赖项,但是我不确定项目是否能正常工作,但是它不再显示缺少这些文件,因此我还在整个项目上添加了try/except
跟踪可能会有所帮助的丢失文件。
我只是在规范文件中添加了丢失的文件和一些hiddenimports
,因此您也需要添加它们。
Start.py
:
import traceback
try:
"""
Whole Start.py script
"""
except Exception:
traceback.print_exc()
while(True):
pass
Start.spec
:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['Start.py'],
pathex=['C:\\Users\\Daniel\\Desktop\\SOAPUIReportingTool-master\\soap'],
binaries=[],
datas=[
("C:\\Program Files\\Python37\\Lib\\site-packages\\tinycss2\\VERSION", "tinycss2"),
("C:\\Program Files\\Python37\\Lib\\site-packages\\cairocffi\\VERSION", "cairocffi"),
("C:\\Program Files\\Python37\\Lib\\site-packages\\\weasyprint\\VERSION", ".")
],
hiddenimports=["tinycss2", "matplotlib", "weasyprint"],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Start',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
runtime_tmpdir=None,
console=True )
答案 1 :(得分:0)
对于将来尝试使WeasyPrint与WINDOWS 10上的PyInstaller一起工作的任何人;我发现以下方法非常有用:
import sys,traceback
try:
import weasyprint
print(weasyprint.__version__)
except:
print(sys.exc_info())
print(traceback.format_exc())
finally:
input('Press enter to exit the program: ')
现在尝试构建:
pyinstaller main.py --name=test --log-level ERROR --clean
它可能会抱怨缺少模块。这是我在数小时的反复试验中混合使用和匹配的方法的地方,我将提供有关如何包括那些缺少的模块的解决方案,以及最终的规格表和方法。
\main.py
\hooks
在此文件夹中,您将使用以下脚本引入python文件,并将其命名为“ hook- {NAMEOFMISSINGMODULE} .py”
from PyInstaller.utils.hooks import collect_data_files
def hook(hook_api):
hook_api.add_datas(collect_data_files(hook_api.__name__))
因此:
\main.py
\hooks
\hook-cssselect2.py
\...
您将在PyInstaller命令中包含以下文件:
pyinstaller main.py --name=test--log-level ERROR --clean --additional-hooks-dir=hooks
pyinstaller main.py --name=test--log-level ERROR --clean --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\weasyprint\css\html5_ph.css;css --additional-hooks-dir=hooks
您是否会抱怨在_MEIXXXXX文件夹中找不到VERSION文件;它正在您的weasyprint软件包中寻找VERSION文件。正确的--add-data行如下:
--add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\weasyprint\VERSION;.
注意分号后跟“。”。这是告诉PyInstaller在打开始终称为_MEI {somerandomnumbers}的exe时,将该文件包含在PyInstaller制作的临时文件夹中。
使用这些方法,您最终应该会成功,并获得weasyprint的版本号。 我最后的工作命令行如下:
pyinstaller main.py --name=test--log-level ERROR --clean --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pyphen;pyphen\dictionaries --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\weasyprint\css\html5_ph.css;css --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\weasyprint\css\html5_ua.css;css --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\weasyprint\VERSION;. --add-data C:\Users\PC\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\cairocffi;cairocffi --additional-hooks-dir=hooks
具有以下挂钩:
\main.py
\hooks
\hook-cairocffi.py
\hook-cssselect2.py
\hook-tinycss2.py
这也适用于一个文件模式。
我肯定知道我可能对钩子和添加数据做了同样的事情;就像我说的那样,我一直在混合和匹配方法,直到最终成功。我非常有信心,仅使用这些方法中的一种就可以达到相同的效果,但是当我已经花了太多时间在上面进行调查时,我认为这样做不值得浪费时间。
感谢所有其他stackoverflow用户和weasyprint创建者,这些年来我在多篇文章中给出了答案,最终我终于可以为自己积累一个工作版本。
如果这有助于给+1或发表评论,因为这是谷歌搜索“ Pyinstaller weasyprint”的第一个答案。