Файл пакета PyInstaller 2.0 как -onefile
Я пытаюсь связать свой py script как .exe с помощью PyInstaller 2.0. Я могу связать script, но в моем script мне нужно открыть файл, который должен быть связан в 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.
Кстати, я использую Win8 64bit с python 2.7.3
ПОЖАЛУЙСТА, ПОМОГИТЕ!
Ответы
Ответ 1
OMG!
Этот PyInstaller действительно немного смутил меня. Если мой предыдущий пост звучит немного "раскосно", извините за это. В любом случае, для тех, кто пытается включить файл в пакет -onefile PyInstaller, это сработало для меня:
Включите это в свой .py script:
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
Это создаст файл myscriptsname.spec в директории pyinstaller-2.0. Он также создаст 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
Это обновит ваш .exe в директории /dist.
Может быть, лучший способ, или более красивый способ, но это сработало для меня!