py2exe - genera un archivo ejecutable único

141

Pensé que escuché que py2exe fue capaz de hacer esto, pero nunca lo descubrí. ¿Alguien ha hecho esto con éxito? ¿Puedo ver su archivo setup.py y qué opciones de línea de comando utilizó?

Básicamente, estoy pensando en que me dé un solo archivo ejecutable que haga algo como descomprimirse en tal vez / temp y se ejecute.

Greg
fuente
¿Se aplica esto a Python 3 o versiones posteriores a python 2?
Vincent

Respuestas:

105

PyInstaller creará un único archivo .exe sin dependencias; usa la --onefileopción Para ello, empaqueta todas las bibliotecas compartidas necesarias en el ejecutable y las desempaqueta antes de que se ejecute, tal como lo describe (EDITAR: py2exe también tiene esta característica, consulte la respuesta de minty )

Uso la versión de PyInstaller de svn, ya que la última versión (1.3) está algo desactualizada. Ha funcionado realmente bien para una aplicación que depende de PyQt, PyQwt, numpy, scipy y algunas más.

dF.
fuente
55
Encontré que py2exe funcionó mucho mejor que pyInstaller, cuando usas huevos. La respuesta de menta es la solución.
gbjbaanb
Tenga en cuenta que a partir de la versión 1.4, PyInstaller no es compatible con Python 2.6+ en Windows
Joril
2
Ahora estoy usando la versión 1.5.1, y funciona con Python 2.7.2.
Oob
1
py2exe puede crear un archivo ejecutable único si especifica algunos argumentos en el programa compilador. py2exe tiene un tutorial para archivos ejecutables de un solo archivo en línea.
trevorKirkby
2
Punto de vista objetivo: no veo cómo esta es una respuesta aceptable, ya que no aborda la cuestión de crear un solo archivo exe con py2exe. (Sin embargo, esta es una respuesta útil, por supuesto).
Jonathan Komar
171

La forma de hacer esto usando py2exe es usar la opción bundle_files en su archivo setup.py. Para un solo archivo, querrá establecerlo bundle_filesen 1,compressed en Verdadero, y establecer la opción de archivo comprimido en Ninguno. De esa manera crea un archivo comprimido para una distribución fácil.

Aquí hay una descripción más completa de la opción bundle_file citada directamente desde el sitio py2exe *

Usando "bundle_files" y "zipfile"

Una manera más fácil (y mejor) de crear archivos ejecutables de un solo archivo es establecer bundle_files en 1 o 2, y establecer zipfile en None. Este enfoque no requiere extraer archivos a una ubicación temporal, lo que proporciona un inicio de programa mucho más rápido.

Los valores válidos para bundle_files son:

  • 3 (predeterminado) no agrupar
  • 2 paquete todo menos el intérprete de Python
  • 1 paquete de todo, incluido el intérprete de Python

Si zipfile está configurado en None, los archivos se agruparán dentro del ejecutable en lugar de library.zip.

Aquí hay un ejemplo de setup.py:

from distutils.core import setup
import py2exe, sys, os

sys.argv.append('py2exe')

setup(
    options = {'py2exe': {'bundle_files': 1, 'compressed': True}},
    windows = [{'script': "single.py"}],
    zipfile = None,
)
menta
fuente
55
Claro, si solo desea que el intérprete no esté incluido, elija 2 para la opción bundle_files. ¡Buena suerte!
menta
13
Tenga en cuenta que bundle_files 1 no es compatible con amd64 (py2exe 0.6.9 para Python 2.6 al menos)
Joril
2
@Pat: La llamada para ejecutar py2exe es "python setup.py py2exe". Al agregar automáticamente el "py2exe" al final, solo significa que no tiene que escribirlo en la línea de comando.
orlade 01 de
2
No es exactamente un único ejecutable, como sea necesario para instalar el archivo DLL de Visual C en tiempo de ejecución Microsoft .
Kevin Smyth
2
Tenía una aplicación de consola que quería tener como un solo ejecutable. Tenía que reemplazar windows = [{'script': "single.py"}]con console = ['single.py']lo que hacer doble clic en el archivo se abrirá en una ventana CMD en Windows.
Jeff B
13

Como menciona el otro póster, py2exe, generará un archivo ejecutable + algunas bibliotecas para cargar. También puede tener algunos datos para agregar a su programa.

El siguiente paso es usar un instalador, para empaquetar todo esto en un programa fácil de usar instalable / ininstalable.

He usado InnoSetup ( http://www.jrsoftware.org/isinfo.php ) con deleite durante varios años y para programas comerciales, así que lo recomiendo encarecidamente.

Philippe F
fuente
+1 para indicar que después de py2exe todavía hay cosas que empaquetar.
joaquin
6

He podido crear un único archivo exe con todos los recursos integrados en el exe. Estoy construyendo sobre ventanas. eso explicará algunas de las llamadas al sistema os que estoy usando.

Primero intenté convertir todas mis imágenes en bitmats y luego todos mis archivos de datos en cadenas de texto. pero esto causó que el exe final fuera muy, muy grande.

Después de googlear durante una semana, descubrí cómo alterar el script py2exe para satisfacer mis necesidades.

aquí está el enlace del parche en sourceforge que envié, publique comentarios para que podamos incluirlo en la próxima distribución.

http://sourceforge.net/tracker/index.php?func=detail&aid=3334760&group_id=15583&atid=315583

esto explica todos los cambios realizados, simplemente agregué una nueva opción a la línea de configuración. Aquí está mi setup.py.

Intentaré comentarlo lo mejor que pueda. Tenga en cuenta que mi setup.py es complejo debido al hecho de que tengo acceso a las imágenes por nombre de archivo. así que debo almacenar una lista para hacer un seguimiento de ellos.

Esto es de un protector de pantalla de querer b que estaba tratando de hacer.

Uso exec para generar mi configuración en tiempo de ejecución, es más fácil cortar y pegar así.

exec "setup(console=[{'script': 'launcher.py', 'icon_resources': [(0, 'ICON.ico')],\
      'file_resources': [%s], 'other_resources': [(u'INDEX', 1, resource_string[:-1])]}],\
      options={'py2exe': py2exe_options},\
      zipfile = None )" % (bitmap_string[:-1])

Descompostura

script = script py quiero pasar a un exe

icon_resources = el icono para el exe

file_resources = archivos que quiero incrustar en el exe

other_resources = una cadena para incrustar en el exe, en este caso una lista de archivos.

opciones = opciones de py2exe para crear todo en un archivo exe

bitmap_strings = una lista de archivos para incluir

Tenga en cuenta que file_resources no es una opción válida hasta que edite su archivo py2exe.py como se describe en el enlace anterior.

La primera vez que intenté publicar código en este sitio, si me equivoco, no me llame.

from distutils.core import setup
import py2exe #@UnusedImport
import os

#delete the old build drive
os.system("rmdir /s /q dist")

#setup my option for single file output
py2exe_options = dict( ascii=True,  # Exclude encodings
                       excludes=['_ssl',  # Exclude _ssl
                                 'pyreadline', 'difflib', 'doctest', 'locale',
                                 'optparse', 'pickle', 'calendar', 'pbd', 'unittest', 'inspect'],  # Exclude standard library
                       dll_excludes=['msvcr71.dll', 'w9xpopen.exe',
                                     'API-MS-Win-Core-LocalRegistry-L1-1-0.dll',
                                     'API-MS-Win-Core-ProcessThreads-L1-1-0.dll',
                                     'API-MS-Win-Security-Base-L1-1-0.dll',
                                     'KERNELBASE.dll',
                                     'POWRPROF.dll',
                                     ],
                       #compressed=None,  # Compress library.zip
                       bundle_files = 1,
                       optimize = 2                        
                       )

#storage for the images
bitmap_string = '' 
resource_string = ''
index = 0

print "compile image list"                          

for image_name in os.listdir('images/'):
    if image_name.endswith('.jpg'):
        bitmap_string += "( " + str(index+1) + "," + "'" + 'images/' + image_name + "'),"
        resource_string += image_name + " "
        index += 1

print "Starting build\n"

exec "setup(console=[{'script': 'launcher.py', 'icon_resources': [(0, 'ICON.ico')],\
      'file_resources': [%s], 'other_resources': [(u'INDEX', 1, resource_string[:-1])]}],\
      options={'py2exe': py2exe_options},\
      zipfile = None )" % (bitmap_string[:-1])

print "Removing Trash"
os.system("rmdir /s /q build")
os.system("del /q *.pyc")
print "Build Complete"

ok, eso es todo para el setup.py ahora la magia necesitaba acceder a las imágenes. Desarrollé esta aplicación sin py2exe en mente y luego la agregué más tarde. así verás acceso para ambas situaciones. Si no se encuentra la carpeta de imágenes, intenta extraer las imágenes de los recursos exe. El código lo explicará. esto es parte de mi clase de sprite y usa un directx. pero puede usar cualquier API que desee o simplemente acceder a los datos sin procesar. no importa

def init(self):
    frame = self.env.frame
    use_resource_builtin = True
    if os.path.isdir(SPRITES_FOLDER):
        use_resource_builtin = False
    else:
        image_list = LoadResource(0, u'INDEX', 1).split(' ')

    for (model, file) in SPRITES.items():
        texture = POINTER(IDirect3DTexture9)()
        if use_resource_builtin: 
            data = LoadResource(0, win32con.RT_RCDATA, image_list.index(file)+1) #windll.kernel32.FindResourceW(hmod,typersc,idrsc)               
            d3dxdll.D3DXCreateTextureFromFileInMemory(frame.device,   #Pointer to an IDirect3DDevice9 interface
                                              data,                #Pointer to the file in memory
                                              len(data),           #Size of the file in memory
                                              byref(texture))      #ppTexture
        else:
            d3dxdll.D3DXCreateTextureFromFileA(frame.device, #@UndefinedVariable
                                               SPRITES_FOLDER + file,
                                               byref(texture))            
        self.model_sprites[model] = texture
    #else:
    #    raise Exception("'sprites' folder is not present!")

Cualquier pregunta fue libre de hacer.

Ni
fuente
He probado su método y funciona bien, pero no entiendo cómo agregar un archivo a la opción file_resurces para incrustar algún archivo en el archivo .exe. Modifiqué el archivo build_exe.py como dijiste, pero cuando entro en el archivo setup.py y lo escribo \'file_resources': [('txt2.txt')]me da un error (el archivo que quiero incrustar en mi .exe se llama txt2 y es un archivo .txt )
VinceLomba
Habló sobre cómo convirtió todas sus imágenes en bitmats y luego todos sus archivos de datos en cadenas de texto. A pesar de que dijiste que hace que el exe sea grande, ¿funciona y, de ser así, puedes decirme cómo hacerlo? Sé que esta respuesta es bastante antigua, pero si puede responder, será apreciada.
Peppa
4

Debe crear un instalador, como se mencionó anteriormente. Aunque también es posible dejar que py2exe agrupe todo en un solo ejecutable, estableciendo la opción bundle_files en 1 y el argumento de la palabra clave zipfile en None, no lo recomiendo para las aplicaciones PyGTK.

Esto se debe a que GTK + intenta cargar sus archivos de datos (locales, temas, etc.) desde el directorio desde el que se cargó. Por lo tanto, debe asegurarse de que el directorio de su ejecutable contenga también las bibliotecas utilizadas por GTK + y los directorios lib, share, etc. de su instalación de GTK +. De lo contrario, tendrá problemas para ejecutar su aplicación en una máquina donde GTK + no está instalado en todo el sistema.

Para más detalles, lea mi guía de py2exe para aplicaciones PyGTK . También explica cómo agrupar todo, pero GTK +.

Sebastian Noack
fuente
1

Me dijeron que bbfreeze creará un único archivo .EXE, y es más nuevo que py2exe.

ℳ.
fuente
3
Por lo que puedo entender, bbfreeze no produce archivos ejecutables de un solo archivo. ¿Podría documentar su respuesta?
joaquin
-2

Recientemente usé py2exe para crear un ejecutable para la revisión posterior para enviar revisiones a ReviewBoard.

Este fue el setup.py que usé

from distutils.core import setup
import py2exe

setup(console=['post-review'])

Creó un directorio que contiene el archivo exe y las bibliotecas necesarias. No creo que sea posible usar py2exe para obtener un solo archivo .exe. Si lo necesita, primero deberá usar py2exe y luego usar algún tipo de instalador para hacer el ejecutable final.

Una cosa a tener en cuenta es que cualquier archivo de huevo que use en su aplicación debe descomprimirse, de lo contrario, py2exe no puede incluirlos. Esto está cubierto en los documentos de py2exe.

David Dibben
fuente
-2

intente congelar c_x puede crear un buen independiente

Denis
fuente
cx_Freeze no puede crear un ejecutable independiente, de hecho, la documentación de cx_Freeze en buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… dice: "cx_Freeze no admite la construcción de un único archivo exe, donde todos las bibliotecas para su aplicación están integradas en un archivo ejecutable ". Para obtener más detalles sobre ejecutables independientes en cx_Freeze, vaya a la documentación ( buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… ) y vaya a la sección 4.5.
Peppa
-6

No, no te da un solo ejecutable en el sentido de que solo tienes un archivo después, pero tienes un directorio que contiene todo lo que necesitas para ejecutar tu programa, incluido un archivo exe.

Acabo de escribir este setup.py hoy. Solo necesitas invocar python setup.py py2exe.

Torsten Marek
fuente
1
Esto no es exacto. Con las opciones correctas, puede obtener un archivo independiente.
trevorKirkby
@Torsten Marek ... el enlace a tu setup.py está muerto. En particular ... los dos primeros redirigidos terminan promocionando material comercial. La tercera vez termina aquí en el callejón sin salida de Internet.
ZF007