py2exe - generuje pojedynczy plik wykonywalny


141

Myślałem, że słyszałem, że py2exe był w stanie to zrobić, ale nigdy tego nie rozgryzłem. Czy ktoś pomyślnie to zrobił? Czy mogę zobaczyć twój plik setup.py i jakich opcji wiersza poleceń użyłeś?

Zasadniczo myślę o tym, że daje mi pojedynczy plik wykonywalny, który robi coś takiego, jak rozpakowuje się do może / temp i działa.


Czy dotyczy to Pythona 3 lub wersji po Pythonie 2?
Vincent,

Odpowiedzi:


105

PyInstaller utworzy pojedynczy plik .exe bez żadnych zależności; skorzystaj z --onefileopcji. Robi to poprzez pakowanie wszystkich potrzebnych bibliotek współdzielonych do pliku wykonywalnego i rozpakowywanie ich przed uruchomieniem, tak jak to opisujesz (EDYCJA: py2exe również ma tę funkcję, zobacz odpowiedź Minty )

Używam wersji PyInstaller z svn, ponieważ najnowsza wersja (1.3) jest nieco przestarzała. Działa naprawdę dobrze w przypadku aplikacji, która zależy od PyQt, PyQwt, numpy, scipy i kilku innych.


5
Odkryłem, że py2exe działa o wiele lepiej niż pyInstaller, gdy używasz jaj. odpowiedź Minty jest rozwiązaniem.
gbjbaanb

Należy pamiętać, że od wersji 1.4 PyInstaller nie obsługuje Pythona 2.6+ w systemie Windows
Joril

2
Używam teraz wersji 1.5.1 i działa z Pythonem 2.7.2.
oob

1
py2exe może utworzyć pojedynczy plik wykonywalny, jeśli określisz kilka argumentów w programie kompilującym. py2exe ma samouczek dotyczący plików wykonywalnych z jednym plikiem w trybie online.
trevorKirkby

2
Obiektywny punkt widzenia: Nie rozumiem, czy jest to akceptowalna odpowiedź, ponieważ nie rozwiązuje problemu tworzenia pojedynczego pliku exe z py2exe. (Niemniej jest to oczywiście przydatna odpowiedź.)
Jonathan Komar

171

Sposobem na zrobienie tego za pomocą py2exe jest użycie opcji bundle_files w pliku setup.py. W przypadku pojedynczego pliku należy ustawić wartość bundle_files1, compressedTrue i ustawić opcję zipfile na None. W ten sposób tworzy jeden skompresowany plik do łatwej dystrybucji.

Oto pełniejszy opis opcji bundle_file cytowanej bezpośrednio z witryny py2exe *

Korzystanie z „bundle_files” i „zipfile”

Łatwiejszym (i lepszym) sposobem tworzenia plików wykonywalnych z jednym plikiem jest ustawienie pliku bundle_files na 1 lub 2 oraz ustawienie pliku zip na Brak. Takie podejście nie wymaga wyodrębniania plików do tymczasowej lokalizacji, co zapewnia znacznie szybsze uruchamianie programu.

Prawidłowe wartości dla bundle_files to:

  • 3 (domyślnie) nie pakuj
  • 2 pakuje wszystko oprócz interpretera Pythona
  • 1 pakuje wszystko, w tym interpreter Pythona

Jeśli plik zipfile ma wartość Brak, pliki zostaną umieszczone w pliku wykonywalnym zamiast w pliku library.zip.

Oto przykład 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
Jasne, jeśli chcesz, aby tylko interpreter nie był dołączany, wybierz 2 dla opcji bundle_files. Powodzenia!
miętowy

13
Należy pamiętać, że bundle_files 1 nie jest obsługiwany na amd64 (py2exe 0.6.9 przynajmniej dla Pythona 2.6)
Joril

2
@Pat: Wywołanie do uruchomienia py2exe to „python setup.py py2exe”. Automatyczne dołączanie „py2exe” na końcu oznacza po prostu, że nie trzeba wpisywać go w wierszu poleceń.
orlade

2
Niezupełnie pojedynczy plik wykonywalny, jak trzeba zainstalować Visual C Runtime DLL Microsoft .
Kevin Smyth

2
Miałem aplikację konsolową, którą chciałem mieć jako pojedynczy plik wykonywalny. Musiałem wymienić windows = [{'script': "single.py"}]ze console = ['single.py']tak dwukrotne kliknięcie na plik otworzy się w oknie CMD w Windows.
Jeff B,

13

Jak wspomniano w innym plakacie, py2exe, wygeneruje plik wykonywalny + kilka bibliotek do załadowania. Możesz także dodać pewne dane do swojego programu.

Następnym krokiem jest użycie instalatora, aby spakować to wszystko w jeden łatwy w użyciu program, który można zainstalować / usunąć.

Z InnoSetup ( http://www.jrsoftware.org/isinfo.php ) korzystam z zachwytem od kilku lat i do programów komercyjnych, więc serdecznie go polecam.


+1 za wskazanie, że po py2exe nadal są rzeczy do spakowania.
joaquin

6

Udało mi się utworzyć pojedynczy plik exe ze wszystkimi zasobami osadzonymi w exe. Buduję na oknach. więc to wyjaśni niektóre z wywołań os.system, których używam.

Najpierw spróbowałem przekonwertować wszystkie moje obrazy na bitmaty, a następnie wszystkie moje pliki danych na ciągi tekstowe. ale to spowodowało, że końcowy exe był bardzo duży.

Po tygodniowym wyszukiwaniu w Google zorientowałem się, jak dostosować skrypt py2exe do moich potrzeb.

tutaj jest link do łatki na sourceforge, które przesłałem, proszę o komentarze, abyśmy mogli je dołączyć do następnej dystrybucji.

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

to wyjaśnia wszystkie wprowadzone zmiany, po prostu dodałem nową opcję do linii ustawień. tutaj jest mój setup.py.

Postaram się to skomentować najlepiej jak potrafię. Pamiętaj, że mój plik setup.py jest skomplikowany, ponieważ mam dostęp do obrazów według nazwy pliku. więc muszę przechowywać listę, aby je śledzić.

pochodzi z wygaszacza ekranu, który chciałem zrobić.

Używam exec do generowania mojej konfiguracji w czasie wykonywania, łatwiej jest wycinać i wklejać w ten sposób.

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

awaria

script = py script Chcę przejść do exe

icon_resources = ikona pliku exe

file_resources = pliki, które chcę osadzić w exe

other_resources = ciąg do osadzenia w exe, w tym przypadku lista plików.

options = py2exe opcje tworzenia wszystkiego w jednym pliku exe

bitmap_strings = lista plików do dołączenia

Pamiętaj, że file_resources nie jest prawidłową opcją, dopóki nie zmodyfikujesz pliku py2exe.py, jak opisano w powyższym linku.

Gdy pierwszy raz próbowałem wysłać kod na tej stronie, jeśli się pomylę, nie pal mnie.

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, to wszystko dla setup.py teraz magia potrzebowała dostępu do obrazów. Opracowałem tę aplikację bez uwzględnienia py2exe, a następnie dodałem ją później. więc zobaczysz dostęp dla obu sytuacji. jeśli nie można znaleźć folderu obrazów, próbuje pobrać obrazy z zasobów exe. kod wyjaśni to. jest to część mojej klasy sprite'a i używa directx. ale możesz użyć dowolnego interfejsu API lub po prostu uzyskać dostęp do surowych danych. nie ma znaczenia.

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!")

Wszelkie pytania nie wahały się zadawać.


Wypróbowałem twoją metodę i działa dobrze, ale nie jestem niepewny, jak dodać plik do opcji file_resurces, aby embledować jakiś plik do .exe. Zmodyfikowałem plik build_exe.py tak, jak powiedziałeś, ale kiedy wchodzę do pliku setup.py i piszę \'file_resources': [('txt2.txt')], pojawia się błąd (plik, który chcę embledować w moim .exe ma nazwę txt2 i jest to plik .txt )
VinceLomba

Mówiłeś o tym, jak przekonwertowałeś wszystkie swoje obrazy na bitmaty, a następnie wszystkie pliki danych na ciągi tekstowe. Mimo że powiedziałeś, że sprawia, że ​​plik exe jest duży, czy to działa, a jeśli tak, czy możesz mi powiedzieć, jak to zrobić? Wiem, że ta odpowiedź jest dość stara, ale jeśli możesz odpowiedzieć, będziemy wdzięczni.
Peppa,

4

Powinieneś utworzyć instalator, jak wspomniano wcześniej. Mimo że możliwe jest również, aby py2exe pakował wszystko w jeden plik wykonywalny, ustawiając opcję bundle_files na 1 i argument słowa kluczowego zipfile na None, nie polecam tego dla aplikacji PyGTK.

Dzieje się tak, ponieważ GTK + próbuje załadować swoje pliki danych (lokalne, motywy itp.) Z katalogu, z którego zostało załadowane. Więc musisz się upewnić, że katalog twojego pliku wykonywalnego zawiera również biblioteki używane przez GTK + oraz katalogi lib, share itp. Z twojej instalacji GTK +. W przeciwnym razie wystąpią problemy z uruchomieniem aplikacji na komputerze, na którym GTK + nie jest zainstalowany w całym systemie.

Aby uzyskać więcej informacji, przeczytaj mój przewodnik po py2exe dla aplikacji PyGTK . Wyjaśnia również, jak spakować wszystko, oprócz GTK +.


1

Powiedziano mi, że bbfreeze utworzy pojedynczy plik .EXE i jest nowszy niż py2exe.


3
O ile rozumiem, bbfreeze nie tworzy plików wykonywalnych jednoplikowych. Czy mógłbyś udokumentować swoją odpowiedź?
joaquin

-1

spróbuj c_x freeze , może stworzyć dobry samodzielny program


cx_Freeze nie może utworzyć samodzielnego pliku wykonywalnego, w rzeczywistości dokumentacja dla cx_Freeze pod adresem buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/ ... mówi: „cx_Freeze nie obsługuje budowania pojedynczego pliku exe, gdzie wszystkie biblioteki aplikacji są osadzone w jednym pliku wykonywalnym ”. Aby uzyskać więcej informacji na temat samodzielnych plików wykonywalnych w cx_Freeze, przejdź do dokumentacji ( buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/ ... ) i przejdź do sekcji 4.5.
Peppa,

-2

Niedawno użyłem py2exe do stworzenia pliku wykonywalnego do późniejszego przeglądu w celu wysłania recenzji do ReviewBoard.

To był plik setup.py, którego użyłem

from distutils.core import setup
import py2exe

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

Utworzył katalog zawierający plik exe i potrzebne biblioteki. Nie sądzę, aby można było użyć py2exe, aby uzyskać tylko jeden plik .exe. Jeśli potrzebujesz tego, musisz najpierw użyć py2exe, a następnie użyć jakiejś formy instalatora, aby utworzyć ostateczny plik wykonywalny.

Jedną rzeczą, na którą należy zwrócić uwagę, jest to, że wszystkie pliki jaj, których używasz w swojej aplikacji, muszą zostać rozpakowane, w przeciwnym razie py2exe nie może ich zawierać. Jest to omówione w dokumentacji py2exe.


-6

Nie, to nie daje ci jednego pliku wykonywalnego w tym sensie, że masz później tylko jeden plik - ale masz katalog, który zawiera wszystko, czego potrzebujesz do uruchomienia programu, w tym plik exe.

Właśnie napisałem ten setup.py dzisiaj. Wystarczy wywołać python setup.py py2exe.


1
To nie jest dokładne. Przy odpowiednich opcjach możesz uzyskać jeden samodzielny plik.
trevorKirkby,

@Torsten Marek ... link do twojego setup.py jest martwy. W szczególności… pierwsze dwa rederekty kończą się promocją treści komercyjnych. Za trzecim razem kończy się tu na martwym końcu internet.
ZF007
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.