Связывание файлов данных с PyInstaller 2.1 и ошибкой MEIPASS --onefile

Этот вопрос задавался ранее, и я не могу заставить мой PyInstaller работать правильно. Я вызвал следующий код в моем файле mainscript.py:

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

Когда я запускаю py-файл (в IDLE), мое приложение отлично работает и загружает все файлы данных. Однако, когда я связываю его с PyInstaller 2.1 (один метод файла), я получаю следующую ошибку после сборки exe:

Traceback (most recent call last):
File "<string>", line 37, in <module>
WindowsError: [Error 3] The system cannot find the path   
specified: 'C:\\Users\\Me\\AppData\\Local\\Temp\\_MEI188722\\eggs/*.*'

У кого-нибудь есть идеи, где я ошибся? Спасибо!

** РЕДАКТИРОВАТЬ **

Вот именно то, что я хочу сделать.

Мой основной скрипт имеет настройки (импорт), которые выглядят как показано ниже. По сути, я хочу иметь возможность использовать Matplotlib, Basemap и путь к ресурсам:

import os,sys
import matplotlib
matplotlib.use('WX')
import wx
from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from mpl_toolkits.basemap import Basemap
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import Calculate_Distance # A personal py file of mine

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

bmap=wx.Bitmap(resource_path('test_image.png'))

print 'hello'

Я использую PyInstaller 2.1. Я также использую Python 2.7.5 (32 бит). Моя ОС - Windows 8 (64-битная). Мой Matplotlib - 1.3.0, а Базовая карта - 1.0.6. Wxpython - 2.8.12.1 (Юникод).

Я иду в команду и делаю: > pyinstaller myscript.py, Это создает мой файл.spec, который я слегка редактирую. Ниже мой отредактированный файл спецификации:

data_files = [('Calculate_Distance.py', 'C:\\Users\\Me\\Documents\\MyFolder\\Calculate_Distance.py',
              'DATA'), ('test_image.png', 'C:\\Users\\Me\\Documents\\MyFolder\\test_image.png',
              'DATA')]

includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
            'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
            'Tkconstants', 'Tkinter']
packages = []
dll_excludes = []
dll_includes = []

a = Analysis(['myscript.py'],
             pathex=['C:\\Users\\Me\\Documents\\MyFolder','C:\\Python27\\Lib\\site-packages\\mpl_toolkits\\basemap\\*'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)

pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries - dll_excludes + dll_includes + data_files,          
          name='MyApplication.exe',
          debug=False,
          strip=None,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name='MyApplication')  

Я хочу, чтобы это был исполняемый файл с одним файлом, поэтому файлы данных должны быть упакованы в исполняемый файл. На других pyinstallers у меня обычно не было проблем с MEIPASS. Однако мне нужно использовать 2.1 из-за Matplotlib и Basemap. Если кто-то может отлично построить этот exe-файл, скажите, пожалуйста, что мне нужно настроить? Спасибо!

****РЕДАКТИРОВАТЬ****

Если кто-нибудь может понять, как это сделать с помощью py2exe - это тоже было бы здорово. Любой способ поместить это в один исполняемый файл стоил бы того!

1 ответ

Я думаю, что вижу проблему. Вы не передаете data_files в свой объект Analysis. Вот как я могу добавить свои файлы данных в мой файл.spec:

a = Analysis(....)
a.datas += [('7z.dll', '7z.dll', 'DATA')]
a.datas += [('7z.exe', '7z.exe', 'DATA')]
a.datas += [('collection.xml', 'collection.xml', 'DATA')]
a.datas += [('License.html', 'License.html', 'DATA')]

pyz = PYZ(a.pure)

exe = EXE(pyz,
          a.scripts + [('O', '', 'OPTION')],
          a.binaries,
          a.zipfiles,
          a.datas,
          name=os.path.join('dist', 'blah.exe'),
          debug=False,
          strip=None,
          upx=False,
          console=True,
          icon=r'..\NCM.ico')

Обратите внимание, что я вообще не использую COLLECT().

Если вы ознакомитесь с документацией 2.1 по адресу: PyInstaller Spec File Operation, вы заметите, что COLLECT() не используется для режима --onefile.

Если вы посмотрите на извлеченный каталог, на который указывает sys._MEIPASS, вы, вероятно, заметите, что в вашем spec-файле файла данных просто нет вообще.

Надеюсь, это поможет.

Другие вопросы по тегам