py2exe: genera un singolo file eseguibile


141

Pensavo di aver sentito che py2exe era in grado di farlo, ma non l'ho mai capito. Qualcuno l'ha fatto con successo? Posso vedere il tuo file setup.py e quali opzioni della riga di comando hai usato?

Fondamentalmente ci sto pensando dandomi un singolo file eseguibile che fa qualcosa come decomprimersi in forse / temp e viene eseguito.


Questo vale per Python 3 o versioni successive a Python 2?
Vincent,

Risposte:


105

PyInstaller creerà un singolo file .exe senza dipendenze; usa l' --onefileopzione. Lo fa impacchettando tutte le librerie condivise necessarie nell'eseguibile e scompattandole prima che vengano eseguite, proprio come descrivi (EDIT: py2exe ha anche questa funzione, vedi la risposta di Menta )

Uso la versione di PyInstaller da svn, poiché l'ultima versione (1.3) è in qualche modo obsoleta. Funziona davvero bene per un'app che dipende da PyQt, PyQwt, numpy, scipy e pochi altri.


5
Ho scoperto che py2exe ha funzionato molto meglio di pyInstaller, quando usi le uova. La risposta di Minty è la soluzione.
gbjbaanb,

Si noti che dalla versione 1.4, PyInstaller non supporta Python 2.6+ su Windows
Joril

2
Ora sto usando la versione 1.5.1 e funziona con Python 2.7.2.
oob

1
py2exe può creare un singolo file eseguibile se si specificano alcuni argomenti nel programma di compilazione. py2exe ha un tutorial per file eseguibili a file singolo online.
trevorKirkby,

2
Punto di vista obiettivo: non vedo come questa sia una risposta accettabile poiché non affronta la questione della creazione di un singolo file exe con py2exe. (Tuttavia, questa è ovviamente una risposta utile.)
Jonathan Komar,

171

Il modo per farlo usando py2exe è usare l'opzione bundle_files nel tuo file setup.py. Per un singolo file dovrai impostare bundle_filessu 1, compressedsu Vero e impostare l'opzione zipfile su Nessuno. In questo modo crea un file compresso per una facile distribuzione.

Ecco una descrizione più completa dell'opzione bundle_file citata direttamente dal sito py2exe *

Utilizzo di "bundle_files" e "zipfile"

Un modo più semplice (e migliore) per creare file eseguibili a file singolo è impostare bundle_files su 1 o 2 e impostare zipfile su None. Questo approccio non richiede l'estrazione di file in una posizione temporanea, che fornisce l'avvio del programma molto più veloce.

I valori validi per bundle_files sono:

  • 3 (impostazione predefinita) non raggruppare
  • 2 raggruppa tutto tranne l'interprete Python
  • 1 raggruppa tutto, incluso l'interprete Python

Se zipfile è impostato su Nessuno, i file saranno raggruppati all'interno dell'eseguibile anziché library.zip.

Ecco un esempio di 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,
)

5
Se vuoi che non sia incluso solo l'interprete, scegli 2 per l'opzione bundle_files. In bocca al lupo!
menta

13
Nota che bundle_files 1 non è supportato su amd64 (almeno py2exe 0.6.9 per Python 2.6)
Joril

2
@Pat: la chiamata per eseguire py2exe è "python setup.py py2exe". Aggiungendo automaticamente "py2exe" alla fine, significa semplicemente che non è necessario digitarlo nella riga di comando.
Orlade,

2
Non esattamente un unico eseguibile, come è necessario installare la DLL Visual C runtime di Microsoft .
Kevin Smyth,

2
Avevo un'applicazione console che volevo avere come singolo eseguibile. Ho dovuto sostituire windows = [{'script': "single.py"}]con un console = ['single.py']doppio clic sul file che si sarebbe aperto in una finestra CMD in Windows.
Jeff B,

13

Come menzionato nell'altro poster, py2exe, genererà un eseguibile + alcune librerie da caricare. Puoi anche avere alcuni dati da aggiungere al tuo programma.

Il prossimo passo è usare un programma di installazione, per impacchettare tutto questo in un programma installabile / non installabile facile da usare.

Ho usato InnoSetup ( http://www.jrsoftware.org/isinfo.php ) con gioia per diversi anni e per programmi commerciali, quindi lo consiglio vivamente.


+1 per indicare che dopo py2exe ci sono ancora cose da imballare.
Joaquin,

6

Sono stato in grado di creare un singolo file exe con tutte le risorse incorporate nell'exe. Sto costruendo su Windows. così che spiegherà alcune delle chiamate os.system che sto usando.

Prima ho provato a convertire tutte le mie immagini in bitmats e poi tutti i miei file di dati in stringhe di testo. ma ciò causò l'exe finale molto grande.

Dopo aver cercato su Google per una settimana, ho capito come modificare lo script py2exe per soddisfare le mie esigenze.

ecco il link della patch su sourceforge che ho inviato, si prega di inviare commenti in modo che possiamo includerlo nella prossima distribuzione.

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

questo spiega tutte le modifiche apportate, ho semplicemente aggiunto una nuova opzione alla riga di installazione. ecco il mio setup.py.

cercherò di commentarlo nel miglior modo possibile. Tieni presente che il mio setup.py è complesso, per il fatto che accedo alle immagini tramite il nome file. quindi devo memorizzare un elenco per tenerne traccia.

questo è da uno screen saver che volevo b che stavo cercando di fare.

Uso exec per generare il mio setup in fase di esecuzione, è più facile tagliarlo e incollarlo in quel modo.

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])

abbattersi

script = py script voglio passare a un exe

icon_resources = l'icona per l'exe

file_resources = file che voglio incorporare nell'esempio

other_resources = una stringa da incorporare nell'exe, in questo caso un elenco di file.

options = py2exe opzioni per la creazione di tutto in un file exe

bitmap_strings = un elenco di file da includere

Si noti che file_resources non è un'opzione valida fino a quando non si modifica il file py2exe.py come descritto nel collegamento sopra.

la prima volta che ho provato a pubblicare il codice su questo sito, se sbaglio non mi eccitare.

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, questo è tutto per setup.py ora la magia necessaria per accedere alle immagini. Ho sviluppato questa app senza py2exe e poi l'ho aggiunta in seguito. quindi vedrai l'accesso per entrambe le situazioni. se non è possibile trovare la cartella delle immagini, tenta di estrarre le immagini dalle risorse exe. il codice lo spiegherà. questo fa parte della mia classe sprite e usa un directx. ma puoi usare qualsiasi API tu voglia o semplicemente accedere ai dati grezzi. non 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!")

Qualsiasi domanda è libera di porre.


Ho provato il tuo metodo e funziona bene, ma non capisco come aggiungere file all'opzione file_resurces per incorporare alcuni file in .exe. Ho modificato il file build_exe.py come hai detto ma quando vado nel file setup.py e scrivo \'file_resources': [('txt2.txt')]mi dà un errore (il file che voglio incorporare nel mio .exe si chiama txt2 ed è un file .txt )
VinceLomba,

Hai parlato di come hai convertito tutte le tue immagini in bitmats e quindi tutti i tuoi file di dati in stringhe di testo. Anche se hai detto che rende l'ex grande, funziona e in tal caso, puoi dirmi come fare? So che questa risposta è piuttosto vecchia ma se puoi rispondere sarà apprezzata.
Peppa,

4

È necessario creare un programma di installazione, come menzionato prima. Anche se è anche possibile lasciare py2exe raggruppare tutto in un singolo eseguibile, impostando l'opzione bundle_files su 1 e l'argomento della parola chiave zipfile su Nessuno, non lo consiglio per le applicazioni PyGTK.

Questo perché GTK + tenta di caricare i suoi file di dati (locali, temi, ecc.) Dalla directory da cui è stato caricato. Quindi devi assicurarti che la directory del tuo eseguibile contenga anche le librerie utilizzate da GTK + e le directory lib, share ed ecc. Dalla tua installazione di GTK +. In caso contrario, si verificheranno problemi nell'esecuzione dell'applicazione su un computer in cui GTK + non è installato a livello di sistema.

Per maggiori dettagli leggi la mia guida a py2exe per le applicazioni PyGTK . Spiega anche come raggruppare tutto, tranne GTK +.


1

Mi è stato detto che bbfreeze creerà un singolo file .EXE ed è più recente di py2exe.


3
Per quanto posso capire, bbfreeze non produce file eseguibili a file singolo. Potresti documentare la tua risposta?
Joaquin,

-2

Recentemente ho usato py2exe per creare un eseguibile per la post-revisione per l'invio di recensioni a ReviewBoard.

Questo era il setup.py che ho usato

from distutils.core import setup
import py2exe

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

Ha creato una directory contenente il file exe e le librerie necessarie. Non penso che sia possibile utilizzare py2exe per ottenere solo un singolo file .exe. Se è necessario, è necessario innanzitutto utilizzare py2exe e quindi utilizzare una qualche forma di programma di installazione per rendere eseguibile finale.

Una cosa di cui occuparsi è che tutti i file uovo che usi nella tua applicazione devono essere decompressi, altrimenti py2exe non può includerli. Questo è trattato nei documenti di py2exe.


-2

prova a congelare c_x può creare un buon standalone


cx_Freeze non può creare un eseguibile autonomo, infatti, la documentazione per cx_Freeze su buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… dice "cx_Freeze non supporta la creazione di un singolo file exe, dove tutto le librerie per la tua applicazione sono incorporate in un file eseguibile. " Per maggiori dettagli sugli eseguibili standalone in cx_Freeze vai alla documentazione ( buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… ) e vai alla sezione 4.5.
Peppa,

-6

No, non ti dà un singolo eseguibile nel senso che in seguito hai solo un file, ma hai una directory che contiene tutto il necessario per eseguire il tuo programma, incluso un file exe.

Ho appena scritto questo setup.py oggi. Devi solo invocare python setup.py py2exe.


1
Questo non è accurato Con le opzioni corrette, è possibile ottenere un file autonomo.
trevorKirkby,

@Torsten Marek ... il link al tuo setup.py è morto. In particolare .. i primi due reindirizzamenti finiscono per promuovere materiale commerciale. La terza volta finisce qui nel vicolo cieco di Internet.
ZF007,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.