20

我正在尝试使用 PyInstaller 2.0 将我的 py 脚本捆绑为 .exe。我可以捆绑脚本,但在我的脚本中,我需要打开一个应该捆绑在 exe 中的文件(因此它是可移植的)。我很难做到这一点..

在我的 .py 中,我有

filename = 'C:\path\to\my\file\doc.docx'
data = open(filename,'rb')

我使用 PyInstaller 2.0,这在我的计算机上运行良好,但如果我将 exe 传输到另一台计算机,它将无法运行。PyInstaller 2.0 是相当新的,所以它上面的文档很少,出版商的文档是相当“缺乏”。

这是发布者关于此事的信息:(我认为他们的文档不是最新的,因为一开始它说使用 Configure.py,然后在其他文档中它说 Configure.py 在 2.0 中不再需要)

在 --onefile 发行版中,数据文件捆绑在可执行文件中,然后在运行时由 C 代码提取到工作目录中(它也能够重建目录树)。工作目录最好通过 os.environ['_MEIPASS2'] 找到。因此,您可以通过以下方式访问这些文件:

os.path.join(os.environ["_MEIPASS2"], relativename))

这对我来说真的没有意义,一个初级程序员..

出版商的另一份文件说..

在 --onefile 发行版中,数据文件捆绑在可执行文件中,然后在运行时由 C 代码提取到工作目录中(它也能够重建目录树)。工作目录最好由 sys._MEIPASS 找到。因此,您可以通过以下方式访问这些文件:

os.path.join(sys._MEIPASS, relativename))

我已经用 os.environ["_MEIPASS2"] 做了很多实验,python 似乎不理解 os.environment["_MEIPASS2"]。我得到了这个:

>>> print os.environ["_MEIPASS2"]

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    print os.environ["_MEIPASS2"]
  File "C:\Python27\lib\os.py", line 423, in __getitem__
    return self.data[key.upper()]
KeyError: '_MEIPASS2'

我还尝试了 sys._MEIPASS .. 是的,python 响应“模块”没有属性“_MEIPASS”。

在这一点上,我觉得我的头快要爆炸了。我感谢 PyInstaller 的作者的工作,但他们的文档是我见过的最糟糕的!我只需要有人帮我将文件捆绑到 exe 中。我真的很想使用 PyInstaller 2.0+,因为所有 .spec 的东西都让我对以前版本的 PyInstaller 感到困惑。

顺便说一句,我正在使用带有 python 2.7.3 的 Win8 64 位

请帮忙!

4

1 回答 1

28

我的天啊!这个 PyInstaller 真的让我有点困惑。如果我以前的帖子听起来有点“咆哮”,对此感到抱歉。无论如何,对于任何试图在 --onefile PyInstaller 包中包含文件的人来说,这对我有用:

将其包含在您的 .py 脚本中:

filename = 'myfilesname.type'
if hasattr(sys, '_MEIPASS'):
    # PyInstaller >= 1.6
    chdir(sys._MEIPASS)
    filename = join(sys._MEIPASS, filename)
elif '_MEIPASS2' in environ:
    # PyInstaller < 1.6 (tested on 1.5 only)
    chdir(environ['_MEIPASS2'])
    filename = join(environ['_MEIPASS2'], filename)
else:
    chdir(dirname(sys.argv[0]))
    filename = join(dirname(sys.argv[0]), filename)

归功于我不记得名字的网上某人..(对不起,来晚了,我筋疲力尽了!)

然后,如果您使用 PyInstaller2.0,在 cmd 中,从 pyinstaller-2.0 目录,您可以运行

pyinstaller.py --onefile myscriptsname.py

这将在 pyinstaller-2.0 目录中创建一个 myscriptsname.spec 文件。它还会创建一个 exe,但这不起作用。稍后会更新。现在编辑该 .spec,并添加以下 a.datas 行(记住数据,而不是数据)。我在 .spec 文件中包含了一些额外内容,仅供参考。

a = Analysis(['ServerTimeTest_nograph.py'],
             pathex=['c:\\Python27\\pyinstaller-2.0'],
             hiddenimports=[],
             hookspath=None)
a.datas += [('myfilesname.type','C:\\path\\to\\my\\file\\myfilesname.type','DATA')]
pyz = PYZ(a.pure)

现在,回到 cmd,运行

pyinstaller.py --onefile myscriptsname.spec

这将更新 /dist 目录中的 .exe。

也许有更好的方法,或者更漂亮的方法,但这对我有用!

于 2012-12-20T00:27:47.643 回答