Py2exe: встроить статические файлы в файл exe и получить к ним доступ
Я нашел решение для добавления файлов в library.zip через: Расширить py2exe для копирования файлов в zip файл, где pkg_resources может их загрузить.
Я могу получить доступ к моему файлу, когда library.zip не включает exe.
Я добавляю файл: text.txt в каталог: foo/media в library.zip.
И я использую этот код:
import pkg_resources
import zipfile
from cStringIO import StringIO
my_data = pkg_resources.resource_string(__name__,"library.zip")
filezip = StringIO(my_data)
zip = zipfile.ZipFile(filezip)
data = zip.read("foo/media/text.txt")
Я пытаюсь использовать pkg_resources, но я думаю, что я ничего не понимаю, потому что я могу открыть непосредственно "library.zip".
Мой вопрос в том, как я могу это сделать, когда library.zip встроен в exe?
С наилучшими пожеланиями
Жан-Мишель
Ответы
Ответ 1
Я объединил достаточно аккуратное решение, но оно не использует pkg_resources.
Мне нужно распространять инструменты производительности как автономные EXE, то есть все, входящие в один .exe файл. Мне также нужно отправлять уведомления, когда эти инструменты используются, что я делаю с помощью API ведения журнала, используя конфигурацию на основе файлов. Я удалил файл logging.cfg, чтобы сделать его более сложным для эффективного отключения этих уведомлений, то есть путем удаления свободного файла... который, вероятно, повредил бы приложение в любом случае.
Итак, следующие интересные биты из моего setup.py:
LOGGING_CFG = open('main/resources/logging.cfg').read()
setup(
name='productivity-tool',
...
# py2exe extras
console=[{'script': productivity_tool.__file__.replace('.pyc', '.py'),
'other_resources': [(u'LOGGINGCFG', 1, LOGGING_CFG)]}],
zipfile=None,
options={'py2exe': {'bundle_files': 1, 'dll_excludes': ['w9xpopen.exe']}},
)
Затем в стартовом коде для performance_tool.py:
from win32api import LoadResource
from StringIO import StringIO
from logging.config import fileConfig
...
if __name__ == '__main__':
if is_exe():
logging_cfg = StringIO(LoadResource(0, u'LOGGINGCFG', 1))
else:
logging_cfg = 'main/resources/logging.cfg'
fileConfig(logging_cfg)
...
Работает с удовольствием!!!
Ответ 2
Спасибо, но я нашел решение
my_data = pkg_resources.resource_stream("__main__",sys.executable) # get lib.zip file
zip = zipfile.ZipFile(my_data)
data = zip.read("foo/media/doc.pdf") # get my data on lib.zip
file = open(output_name, 'wb')
file.write(data) # write it on a file
file.close()
С наилучшими пожеланиями
Ответ 3
Вы не должны использовать pkg_resources для извлечения файла library.zip. Вы должны использовать его для извлечения добавленного ресурса.
Предположим, что у вас есть следующая структура проекта:
setup.py
foo/
__init__.py
bar.py
media/
image.jpg
Для доступа к image.jpg:
вы должны использовать resource_string (или, желательно, resource_stream)
img = pkg_resources.resource_string(__name__, 'media/image.jpg')
Это должно "просто работать". По крайней мере, это произошло, когда я связал свои медиафайлы в EXE. (Извините, с тех пор я покинул компанию, где я использовал py2exe, поэтому нет рабочего примера для рисования.)
Вы также можете попробовать использовать pkg_resources.resource_filename(), но я не думаю, что это работает под py2exe.