Файл пакета 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.

Может быть, лучший способ, или более красивый способ, но это сработало для меня!