python - Archivo de paquete PyInstaller 2.0 como--onefile
(1)
Estoy tratando de empaquetar mi script py como un archivo .exe usando PyInstaller 2.0. Soy capaz de empaquetar el script, pero en mi script, necesito abrir un archivo que debería estar empaquetado en el archivo ejecutable (por lo que es portátil). Estoy teniendo problemas para hacer esto ...
En mi .py, tengo
filename = ''C:/path/to/my/file/doc.docx''
data = open(filename,''rb'')
Utilizo PyInstaller 2.0 y esto funciona bien en mi computadora, pero si transfiero el archivo exe a otra computadora no va a funcionar. PyInstaller 2.0 es bastante nuevo, por lo que hay muy pocos documentos, y la documentación del editor es bastante "carente".
Aquí está la información del editor sobre el tema: (No creo que su documentación esté actualizada, porque al principio dice que use Configure.py, luego en otros documentos dice que Configure.py ya no es necesario en 2.0)
En una distribución de - OneFile, los archivos de datos se agrupan en el ejecutable y luego se extraen en el tiempo de ejecución en el directorio de trabajo mediante el código C (que también puede reconstruir los árboles de directorios). El directorio de trabajo se encuentra mejor en os.environ [''_ MEIPASS2'']. Entonces, puedes acceder a esos archivos a través de:
os.path.join(os.environ["_MEIPASS2"], relativename))
Eso realmente no tiene sentido para mí, un programador principiante ..
Un documento diferente del editor dice ...
En una distribución de - OneFile, los archivos de datos se agrupan en el ejecutable y luego se extraen en el tiempo de ejecución en el directorio de trabajo mediante el código C (que también puede reconstruir los árboles de directorios). El directorio de trabajo se encuentra mejor por sys._MEIPASS. Entonces, puedes acceder a esos archivos a través de:
os.path.join(sys._MEIPASS, relativename))
He experimentado bastante con os.environ ["_ MEIPASS2"] y python no parece entender os.environment ["_ MEIPASS2"]. Recupero esto
>>> 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''
También experimenté con sys._MEIPASS ... Sí, Python responde que ''módulo'' no tiene atributo ''_MEIPASS''.
En este punto, siento que mi cabeza está a punto de explotar ... Aprecio a los autores de PyInstaller por su trabajo, ¡pero su documentación es la peor que he visto! Solo necesito a alguien que me ayude a agrupar mi archivo en el exe. Realmente me gustaría usar PyInstaller 2.0+ ya que todo lo relacionado con .spec me confunde con las versiones anteriores de PyInstaller.
Por cierto, estoy usando Win8 de 64 bits con python 2.7.3
¡POR FAVOR AYUDA!
¡DIOS MIO! Este PyInstaller realmente me confundió por un momento. Si mi publicación anterior suena un poco "ranty", lo siento ... De todos modos, para cualquiera que intente incluir un archivo en un paquete PyInstaller --onefile, esto funcionó para mí:
Incluya esto en su 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édito a alguien en línea cuyo nombre no recuerdo ... (lo siento, es tarde y estoy agotado!)
Luego, si está utilizando PyInstaller2.0, en cmd, desde el directorio pyinstaller-2.0, puede ejecutar
pyinstaller.py --onefile myscriptsname.py
Eso creará un archivo myscriptsname.spec en el directorio pyinstaller-2.0. También creará un exe, pero eso no funcionará. Se actualizará más tarde. Ahora edite ese .spec, y agregue la siguiente línea a.datas (recuerde datos, no datos). Incluí un poco más en el archivo .spec solo como referencia.
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)
Ahora, de vuelta en cmd, corre
pyinstaller.py --onefile myscriptsname.spec
Esto actualizará su .exe en el directorio / dist.
Tal vez hay una mejor manera, o una forma más bonita, pero esto funcionó para mí!