Py2exe: встроить статические файлы в сам файл exe и получить к ним доступ - PullRequest
10 голосов
/ 21 декабря 2009

Я нашел решение добавить файлы в library.zip через: Расширить py2exe для копирования файлов в zipfile, где 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?

С наилучшими пожеланиями

Jean-Michel

Ответы [ 3 ]

10 голосов
/ 10 сентября 2010

Я собрал достаточно аккуратное решение для этого, но он не использует 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)
    ...

Работает угощение !!!

1 голос
/ 11 марта 2010

Спасибо, но я нашел решение

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()

С наилучшими пожеланиями

0 голосов
/ 15 января 2010

Вы не должны использовать pkg_resources для получения файла library.zip. Вы должны использовать его для извлечения добавленного ресурса.

Предположим, у вас есть следующая структура проекта:

setup.py
foo/
    __init__.py
    bar.py
    media/
        image.jpg

Вы должны использовать resource_string (или, предпочтительно, resource_stream) для доступа к image.jpg:

img = pkg_resources.resource_string(__name__, 'media/image.jpg')

Это должно "просто работать". По крайней мере, так было, когда я упаковал свои медиа файлы в EXE. (Извините, с тех пор я покинул компанию, где использовал py2exe, поэтому у меня нет рабочего примера для рисования.)

Вы также можете попробовать использовать pkg_resources.resource_filename (), но я не думаю, что это работает под py2exe.

...