Python PyInstaller 2.0捆绑文件为--onefile

Python PyInstaller 2.0捆绑文件为--onefile,python,pyinstaller,Python,Pyinstaller,我正在尝试使用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是一个

我正在尝试使用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[''u MEIPASS2']找到。因此,您可以通过以下方式访问这些文件:

这对我这个初学编程的人来说真的没什么意义

一份与出版商不同的文件上说

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

我在os.environ[“\u MEIPASS2”]上做了很多实验,python似乎不理解os.environment[“\u 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'
打印操作系统环境[“\u MEIPASS2”] 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 打印操作系统环境[“_MEIPASS2”] 文件“C:\Python27\lib\os.py”,第423行,在\uu getitem中__ 返回self.data[key.upper()] KeyError:“\u MEIPASS2” 我还试验了sys.\u MEIPASS。。是的,python响应“module”没有属性“\u MEIPASS”

在这一点上,我觉得我的头快要爆炸了。。我感谢PyInstaller的作者们的工作,但他们的文档是我见过的最糟糕的!我只需要有人帮我把文件打包到exe中。我真的很想使用PyInstaller 2.0+,因为所有的.spec内容让我与PyInstaller的早期版本混淆

顺便说一句,我在Python2.7.3中使用Win8 64位

请帮忙

天哪! 这个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)
这将在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


也许有更好的方法,或者更漂亮的方法,但这对我来说很有效

AFAIU,
--onefile
在拥有规范文件时是不必要的;否则看起来“版本1是
\u-MEIPASS2
,版本2是
\u-MEIPASS
”——这让人困惑,但知道这一点非常有用,谢谢你们(在线人士和你自己)@ジョージ 你说得对
--onedir
--onefile
直接创建规范文件。如果您使用已生成的.spec文件调用pyinstaller,则不需要使用这些选项。太好了,您已经保存了我的应用程序。要使修复程序正常工作,请确保在
.py
脚本中包含
from os.path import join
from os import chdir
,如果您还没有。只需使用
sys.\u MEIPASS
获取应用程序根路径。IDE会给你一个错误/警告,但在应用程序内部它会工作。默认情况下,它类似于:
C:\Users\[USER]\AppData\Local\Temp\\u MEIXXXXX
pyinstaller.py --onefile myscriptsname.py
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)
pyinstaller.py --onefile myscriptsname.spec