Pyinstaller onefile找不到数据文件

时间:2013-01-12 18:56:52

标签: python exe executable pyinstaller

我也是第一次尝试构建一个包含数据文件的简单的--onefile exe,但是在构建.exe时Pyinstaller似乎没有找到它们。一个--onedir build似乎工作正常。

此时我也在使用--debug开关。我能够运行onefile可执行文件,可以看到它似乎开始工作。程序找到(sys._MEIPASS)临时目录ok(按照指示打印所需的目录名称),但在从temp目录中查找第一个数据文件时报告“没有这样的文件或目录”错误。我在.exe上使用了archiveviewer.py而DID却找不到所需的数据文件 - 这似乎是问题所在,但我无法弄清楚原因。构建的数据文件位于spec文件描述的目录中。我的完整spec文件是

# -*- mode: python -*-

a = Analysis(['develop6.py'],
         pathex=['C:\\PYINST20'],
         hiddenimports=[],
         hookspath=None)

a.datas += [ ('conlist.txt', 'C:\\pyinst20\\conlist.txt', 'DATA'), ('imageblank.gif', 'C:\\pyinst20\\imageblank.gif', 'DATA')]

pyz = PYZ(a.pure)

exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name=os.path.join('dist', 'develop6.exe'),
      debug=True,
      strip=None,
      upx=True,
      console=True )

5 个答案:

答案 0 :(得分:1)

confusing stack overflow threadsPyinstaller文档之间前后移动后,我终于捆绑了我的应用。

一步一步:

  1. 在您的应用根目录和. venv/bin/activate d:

    ➜  ~ pip install pyinstaller
    ➜  ~ pyi-makespec --windowed --onedir --i ./resources/img/icn.icns \
          --osx-bundle-identifier "com.myname.macOS.myappname" app.py
    
  2. 现在,稍微修改一下app.spec

    added_files = [
     ('resources/img', 'resources/img'),
     ( 'README.md', '.' )
     ]
    

    使用资源的相对路径初始化dictionary added_files并设置datas = added_files。在我的应用程序中,我使用位于./resources/img相对于我的main.py文件的图像。

  3. 最终,这可能是最容易忘记的步骤而不是那么明显:

    ➜  ~ pyinstaller --onefile app.spec
    
  4. 请注意,最后一步取自here

答案 1 :(得分:1)

(这个问题很旧,但这是我发现解决同一问题的唯一途径之一,我将在这里分享我的解决方案,以防它可以帮助某人)

要以--onefile模式将数据文件添加到脚本中,需要做两件事。

1。调整路径

在脚本中,调整路径以查找捆绑软件中的数据文件。 根据PyInstaller文档here,可执行文件是从临时文件启动的,因此您的路径必须处理此动态部分:

对于具有以下相对路径的文件: ./your/file/is/here.ext

代码为:

import sys
wd = sys._MEIPASS
file_path = os.path.join(wd,<your>,<file>,<is>,<here>)

注意:要使您的代码也可以在其他上下文中工作,可以执行以下操作:

import sys
import os
try:
   wd = sys._MEIPASS
except AttributeError:
   wd = os.getcwd()
file_path = os.path.join(wd,<your>,<file>,<is>,<here>)

2。在PyInstaller规范中添加数据文件路径

根据PyInstaller文档here,有两种方法可将数据文件添加到包中:

  1. 从脚本目录运行--add-files时,将选项pyinstaller <yourscript.py>和文件作为参数传递

  2. 首先通过导航到脚本目录并运行pyi-makespec <yourscript.py>来生成规格文件,然后将文件添加到元组列表data=[]中。 元组包含文件的实际路径以及其中的路径 您的捆绑包。如果您遵循了第一点,应该看起来像 datas = [('/your/file/is/here.ext','/your/file/is/')]

然后根据您的规格文件运行PyInstall <yourscript.spec>来构建捆绑包。

答案 2 :(得分:0)

我相信我发现了问题,它与spec文件的正文无关。在使用spec文件运行pyinstaller时,我的命令行语法看起来是错误的。运行正常时:

pyinstaller.py [options] <my_specfile.spec>

似乎有效。

答案 3 :(得分:0)

无论脚本是否捆绑运行,我们都可以按照document设置不同的文件路径。但是,我的解决方法是在所有非脚本文件都存在的地方建立一个稳定的顶层目录,并与所有模块共享该顶层目录。然后,在每个模块中,我可以基于顶层目录创建文件路径。

例如,在此布局中,所有模块代码都位于src文件夹中。这些模块要求访问conf文件夹,database文件夹和otherconfig.yaml

├── conf
│   └── config.ini
├── database
├── entry_point.py
├── otherconfig.yaml
├── root_path.py
└── src
    ├── pkg1
    └── pkg2

root_path.py看起来像这样:

import os

path = os.getcwd()

在每个模块中,我可以为配置文件创建文件路径,如下所示:

import root_path

config_path = f"{root_path.path}/conf/config.ini"
otherconfig_path = f"{root_path.path}/otherconfig.yaml"

然后,在通过pyinstaller -F entry_point.py创建一个文件可执行文件(不添加任何文件)之后,我们只需要重新创建相同的布局,每个模块中的文件路径仍然可以使用。

├── bundled_executable
├── conf
│   └── config.ini
├── database
└── otherconfig.yaml

当然,此替代方法无法隐藏配置文件。但是对于我的用例,我需要给用户自由修改配置文件的权限,以免隐藏文件对我真正有用。

答案 4 :(得分:0)

使用AutoPyToExe之类的应用程序可以解决PyInstaller面临的大多数挑战。该界面使您可以解决此处列出的大多数挑战。只需选择文件的位置,而不必四处移动,即可查看附件中隐藏文件,数据文件,清理构建以及其他内容的方式。

enter image description here