web-dev-qa-db-fra.com

PyInstaller 2.0 bundle file as --onefile

J'essaie de regrouper mon script py en tant que .exe à l'aide de PyInstaller 2.0. Je suis en mesure de regrouper le script, mais dans mon script, j'ai besoin d'ouvrir un fichier qui devrait être regroupé dans l'exe (donc c'est portable). J'ai du mal à faire ça ..

Dans mon .py, j'ai

filename = 'C:\path\to\my\file\doc.docx'
data = open(filename,'rb')

J'utilise PyInstaller 2.0 et cela fonctionne très bien sur mon ordinateur, mais si je transfère l'exe vers un autre ordinateur, cela ne fonctionnera pas. PyInstaller 2.0 est assez nouveau, donc il y a très peu de documents dessus, et la documentation de l'éditeur est assez "manquant".

Voici les informations de l'éditeur à ce sujet: (Je ne pense pas que leur documentation soit à jour, car au début, il est dit utiliser Configure.py, puis dans d'autres documents, il est dit que Configure.py n'est plus nécessaire en 2.0)

Dans une distribution --onefile, les fichiers de données sont regroupés dans l'exécutable puis extraits lors de l'exécution dans le répertoire de travail par le code C (qui est également capable de reconstruire des arborescences de répertoires). Le répertoire de travail est mieux trouvé par os.environ ['_ MEIPASS2']. Ainsi, vous pouvez accéder à ces fichiers via:

os.path.join(os.environ["_MEIPASS2"], relativename))

Cela n'a pas vraiment de sens pour moi, un programmeur débutant ..

Un document différent de l'éditeur dit ..

Dans une distribution --onefile, les fichiers de données sont regroupés dans l'exécutable puis extraits lors de l'exécution dans le répertoire de travail par le code C (qui est également capable de reconstruire des arborescences de répertoires). Le répertoire de travail est mieux trouvé par sys._MEIPASS. Ainsi, vous pouvez accéder à ces fichiers via:

os.path.join(sys._MEIPASS, relativename))

J'ai beaucoup expérimenté avec os.environ ["_ MEIPASS2"] et python ne semble pas comprendre os.environment ["_ MEIPASS2"]. Je récupère ceci:

>>> 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'

J'ai également expérimenté avec sys._MEIPASS .. Oui, python répond 'module' n'a pas d'attribut '_MEIPASS'.

À ce stade, j'ai l'impression que ma tête est sur le point d'exploser .. J'apprécie les auteurs de PyInstaller pour leur travail, mais leur documentation est la pire que j'aie jamais vue! J'ai juste besoin de quelqu'un pour m'aider à regrouper mon fichier dans l'exe. Je voudrais vraiment utiliser PyInstaller 2.0+ car tous les trucs .spec me confondent avec les versions précédentes de PyInstaller.

BTW, j'utilise Win8 64bit avec python 2.7.3

SVP AIDEZ!

19
user1914730

OMG! Ce PyInstaller m'a vraiment un peu dérouté. Si mon message précédent semble un peu "délirant", désolé à ce sujet .. Quoi qu'il en soit, pour quiconque essaie d'inclure un fichier dans un package --onefile PyInstaller, cela a fonctionné pour moi:

Incluez ceci dans votre script .py:

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)

crédit à quelqu'un en ligne dont je ne me souviens pas du nom .. (désolé il est tard et je suis épuisé!)

Ensuite, si vous utilisez PyInstaller2.0, en cmd, à partir du répertoire pyinstaller-2.0, vous pouvez exécuter

pyinstaller.py --onefile myscriptsname.py

Cela créera un fichier myscriptsname.spec dans le répertoire pyinstaller-2.0. Cela créera également un exe, mais cela ne fonctionnera pas. Il sera mis à jour ultérieurement. Modifiez maintenant ce .spec et ajoutez la ligne a.datas suivante (rappelez-vous les données, pas les données). J'ai inclus un petit plus dans le fichier .spec juste pour référence.

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)

Maintenant, de retour en cmd, exécutez

pyinstaller.py --onefile myscriptsname.spec

Cela mettra à jour votre .exe dans le répertoire/dist.

Il y a peut-être une meilleure façon, ou une plus jolie, mais cela a fonctionné pour moi!

27
user1914730