[Python] Comment inclure des données dans un fichier .exe créé avec py2exe
Par Florent Manens, lundi 16 janvier 2006 à 23:21 :: Informatique :: #29 :: rss
Contexte
Python est un langage interprété, afin d'exécuter un script python, il faut l'interpréteur Python. Cependant, avec le logiciel py2exe, il est possible de créer un fichier .exe contenant l'ensemble du programme et ses dépendances (dll python + un script).
Cependant, dans certains cas, il peut être intéressant d'inclure d'autres données avec le fichier exécutable comme par exemple des images ou des fichiers de données.
L'objectif ici est d'obtenir un seul fichier contenant :
- l'interpréteur python
- un script, potentiellement réparti sur plusieurs fichiers
- un fichier de données
Prérequis
Premièrement, je recommende d'utiliser la version 2.3 de python, elle n'est pas encore dépassée et surtout, elle permet de se passer des la DLL qui est nécessaire à python 2.4 : msvcr71.dll.
Pour créer un exe contenant l'ensemble des fichiers, il faut au moins la version 0.6 de py2exe.
L'astuce
Fortement inspiré par le script img2py.py que l'on trouve dans la bibliothèque wxWidget, j'ai écri le script tout simple data2py.py que voici :
import os import sys import getopt __doc__ = """ convert file into an importable module data2py.py toto.dat >toto.py extract from python : import toto f = file("toto.dat", "wb") f.write(toto.data.decode("base64")) """ def main(args): if not args or ("-h" in args): print __doc__ return try: opts, fileArgs = getopt.getopt(args, "") except getopt.GetoptError: print __doc__ return f = file(fileArgs[0], "rb") buff = f.read() print "data = %s%s%s" % ('"""', buff.encode("base64"), '"""') if __name__ == "__main__": main(sys.argv[1:])
Pour l'utiliser il suffit de faire :
python data2py.py text.txt >text.py
Contenu de text.py :
data = """Qm9uam91ciE= """
Le script crée un fichier python contenant les données correspondantes au fichier d'origine mais encodé en base64. Ensuite, un import donnera accès aux données.
Pour créer un nouveau fichier :
import text f = file("text.txt", "wb") f.write(text.data.decode("base64")) f.close()
Pour afficher le contenu du fichier :
import text print text.data.decode("base64")
Création du fichier .exe
Pour créer un fichier .exe avec py2exe, il faut passer par un fichier setup.py. Il n'y a rien de particulier à faire ici, un script classique suffira :
import py2exe from distutils.core import setup setup(console = ["test.py"], options = {"py2exe": {"optimize": 2, "bundle_files": 1, "compressed": 1}}, zipfile = None)
Il suffit de créer le fichier .exe ainsi :
python setup.py py2exe
On obtient un fichier unique ! Il reste juste un problème dans le cas de la diffusion vers Win9X, le fichier w9xpopen.exe est nécessaire.
Conclusion
C'est simple non ? Python est un bon langage ! Plus je l'utilise et plus je suis épaté par sa simplicité.
Il existe d'autres méthodes pour arriver à un résultat proche. En particulier cette solution, basée sur ctype et une autre solution en utilisant NSIS (moins pratique, elle ne permet pas d'utiliser la ligne de commande).
Améliorations possibles
On pourrait envisager une petite automatisation de la mise en place des fichiers dans le module et l'utilisation de la zlib pour gagner un peu de place (histoire de compenser un peu la place perdue avec l'utilisation de Base64). Justement en parlant de gain de place, il est aussi possible d'automatiser l'utilisation de UPX (UPX, outil multiplateforme, permet de comprimer les .exe. Il ne fonctionne pas sur un .exe résultant de py2exe mais peut être utilisé sur les dlls).
Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire