【问题标题】:Add config file outside Pyinstaller --onefile exe into dist directory将 Pyinstaller --onefile exe 之外的配置文件添加到 dist 目录
【发布时间】:2021-01-15 22:41:53
【问题描述】:

情况

我在 Windows 上使用 Pyinstaller 为我的项目制作一个 .exe 文件。

我想使用--onefile 选项来获得干净的结果和易于分发的文件/程序。

我的程序使用config.ini 文件来存储配置选项。该文件可由用户自定义。

问题

使用 --onefile 选项 Pyinstaller 将所有声明的“数据文件”放入单个 .exe 文件文件中。

我见过这个request,但它提供了在.exedist 的同一级别添加捆绑文件在onefile 内部 而不是外部的指示目录。

在某些时候,我曾想过在 .spec 文件中使用 shutil.copy 命令来复制此文件...但我认为这是错误的方式。

有人可以帮我吗?我会很感激的:-)

【问题讨论】:

  • 我也有同样的问题。
  • 我希望得到一些建议,以了解是否有可能直接使用 Pyinstaller 获得此结果。目前我已经看到很多关于 - - onefile 选项的这种行为的问题,但没有找到解决方案。
  • 嗨@RicardoDuarte 我找到了一种将外部数据文件添加到 PyInstaller --onefile 命令的自动方法。看看答案,让我知道它是否也适合你。
  • 您可以按照以下简单解决方案的说明进行操作:stackoverflow.com/a/63069583/5068961

标签: python pyinstaller


【解决方案1】:

A repository on Github 帮助我找到了问题的解决方案。

我使用了shutil 模块和.spec 文件,使用Pyinstaller --onefile 选项将额外的数据文件(在我的情况下是config-sample.ini 文件)添加到dist 文件夹。

为 pyinstaller 创建一个 .spec 文件

首先,我创建了一个包含所需选项的 makespec 文件:

$ pyi-makespec --onefile --windowed --name exefilename scriptname.py

此命令创建一个 exefilename.spec 文件以与 Pyinstaller 一起使用

修改exefilename.spec 添加shutil.copyfile

现在我已经编辑了exefilename.spec,在文件末尾添加了以下代码。

import shutil
shutil.copyfile('config-sample.ini', '{0}/config-sample.ini'.format(DISTPATH))
shutil.copyfile('whateveryouwant.ext', '{0}/whateveryouwant.ext'.format(DISTPATH))

此代码在编译过程结束时复制所需的数据文件。 您可以使用 shutil 包中提供的所有方法。

运行 PyInstaller

最后一步是运行编译过程

pyinstaller --clean exefilename.spec

结果是,在 dist 文件夹中,您应该将已编译的 .exe 文件与复制的数据文件一起复制。

考虑

在 Pyinstaller 的官方文档中,我没有找到获得此结果的选项。我认为它可以被认为是一种解决方法......有效。

【讨论】:

  • 美丽。感谢您发帖。
  • 我知道这是一个旧答案,但我仍在寻找这个问题的解决方案。这个答案有很多赞成票,所以我认为我遗漏了一些东西。这会将配置文件复制到与可执行文件相同的目录,但似乎没有任何方式在运行时将配置文件的路径提供给 exe。这个问题在这个答案stackoverflow.com/questions/60937345/… 中得到了解决,但没有解决文件与 onefile exe 位于同一目录中的问题
【解决方案2】:

我的解决方案类似于@Stefano-Giraldi 的出色解决方案。将目录传递给 shutil.copyfile 时,我的权限被拒绝。

我最终使用了shutil.copytree

import sys, os, shutil

site_packages = os.path.join(os.path.dirname(sys.executable), "Lib", "site-packages")
added_files = [
                (os.path.join(site_packages, 'dash_html_components'), 'dash_html_components'),
                (os.path.join(site_packages, 'dash_core_components'), 'dash_core_components'),
                (os.path.join(site_packages, 'plotly'), 'plotly'),
                (os.path.join(site_packages, 'scipy', '.libs', '*.dll'), '.')
                ]
working_dir_files = [
                ('assets', 'assets'),
                ('csv', 'csv')
                ]

print('ADDED FILES: (will show up in sys._MEIPASS)')
print(added_files)
print('Copying files to the dist folder')

print(os.getcwd())
for tup in working_dir_files:
        print(tup)
        to_path = os.path.join(DISTPATH, tup[1])
        if os.path.exists(to_path):
                if os.path.isdir(to_path):
                        shutil.rmtree(to_path)
                else:
                        os.remove(to_path)
        if os.path.isdir(tup[0]):
                shutil.copytree(tup[0], to_path )
        else:
                shutil.copyfile(tup[0], to_path )

#### ... Rest of spec file
a = Analysis(['myapp.py'],
             pathex=['.', os.path.join(site_packages, 'scipy', '.libs')],
             binaries=[],
             datas=added_files,
             hiddenimports=[],
             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='myapp',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True )

这避免了 _MEI 文件夹,并防止它在 dist 文件夹中复制您想要的配置文件,而不是在临时文件夹中。

希望对您有所帮助。

【讨论】:

  • 感谢您的认可。我很高兴对你有用。 :-)
猜你喜欢
  • 2013-05-18
  • 2020-03-23
  • 2019-01-16
  • 2020-12-17
  • 2022-10-17
  • 2020-09-12
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多