py2exe - สร้างไฟล์เรียกทำงานไฟล์เดียว


141

ฉันคิดว่าฉันได้ยินมาว่าpy2exeสามารถทำสิ่งนี้ได้ แต่ฉันไม่เคยคิดเลย มีใครทำเช่นนี้สำเร็จหรือไม่ ฉันสามารถดูไฟล์ setup.py ของคุณและตัวเลือกบรรทัดคำสั่งใดที่คุณใช้บ้าง

โดยทั่วไปฉันกำลังคิดว่าจะให้ไฟล์ที่สามารถเรียกใช้งานได้เพียงไฟล์เดียวซึ่งทำสิ่งต่าง ๆ เช่นคลายซิปตัวเองไปจนถึง / temp และรัน


สิ่งนี้ใช้ได้กับ Python 3 หรือรุ่นหลังจาก python 2 หรือไม่
Vincent

คำตอบ:


105

PyInstallerจะสร้างไฟล์. exe ไฟล์เดียวโดยไม่มีการขึ้นต่อกัน; ใช้--onefileตัวเลือก ทำได้โดยบรรจุ libs ที่ใช้ร่วมกันที่จำเป็นทั้งหมดลงในปฏิบัติการและแกะกล่องออกก่อนที่จะทำงานตามที่คุณอธิบาย (แก้ไข: py2exe ยังมีคุณสมบัตินี้ดูคำตอบของ minty )

ฉันใช้เวอร์ชั่น PyInstaller จาก svn เนื่องจากรุ่นล่าสุด (1.3) ค่อนข้างล้าสมัย มันทำงานได้ดีมากสำหรับแอปที่ขึ้นอยู่กับ PyQt, PyQwt, numpy, scipy และอีกไม่กี่อย่าง


5
ฉันพบว่า py2exe ทำงานได้ดีกว่า pyInstaller มากเมื่อคุณใช้ไข่ คำตอบของ minty คือทางออก
gbjbaanb

โปรดทราบว่าในเวอร์ชั่น 1.4 PyInstaller ไม่รองรับ Python
2.6+

2
ตอนนี้ฉันใช้เวอร์ชั่น 1.5.1 และใช้งานได้กับ Python 2.7.2
oob

1
py2exe สามารถสร้างไฟล์เดียวที่ปฏิบัติการได้หากคุณระบุอาร์กิวเมนต์บางอย่างในโปรแกรมคอมไพเลอร์ py2exe มีบทช่วยสอนสำหรับไฟล์เรียกทำงานเดี่ยวแบบออนไลน์
trevorKirkby

2
ทัศนะวัตถุประสงค์: ฉันไม่เห็นว่านี่เป็นคำตอบที่ยอมรับได้เพราะไม่ได้ตอบคำถามของการสร้างไฟล์ exe เดี่ยวด้วย py2exe (อย่างไรก็ตามนี่เป็นคำตอบที่เป็นประโยชน์แน่นอน)
Jonathan Komar

171

วิธีการทำเช่นนี้โดยใช้ py2exe คือการใช้ตัวเลือก bundle_files ในไฟล์ setup.py ของคุณ สำหรับไฟล์เดียวคุณจะต้องตั้งค่าbundle_filesเป็น 1 compressedถึง True และตั้งค่าตัวเลือก zipfile เป็น None ด้วยวิธีนี้มันจะสร้างไฟล์บีบอัดหนึ่งไฟล์เพื่อให้กระจายได้ง่าย

นี่คือคำอธิบายที่สมบูรณ์มากขึ้นของตัวเลือก bundle_file ที่ยกมาโดยตรงจากไซต์ py2exe *

ใช้ "bundle_files" และ "zipfile"

วิธีที่ง่ายกว่า (และดีกว่า) ในการสร้างไฟล์เรียกทำงานไฟล์เดียวคือตั้งค่า bundle_files เป็น 1 หรือ 2 และตั้งค่า zipfile เป็น None วิธีการนี้ไม่ต้องการให้แตกไฟล์ไปยังตำแหน่งชั่วคราวซึ่งจะทำให้การเริ่มต้นโปรแกรมเร็วขึ้นมาก

ค่าที่ถูกต้องสำหรับ bundle_files คือ:

  • 3 (ค่าเริ่มต้น) อย่ามัด
  • 2 รวมทุกอย่างยกเว้น Python interpreter
  • 1 รวมทุกอย่างรวมถึง Python interpreter

หาก zipfile ถูกตั้งค่าเป็น None ไฟล์จะถูกบันเดิลภายในไฟล์ที่เรียกทำงานได้แทนที่จะเป็น library.zip

นี่คือตัวอย่าง 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
แน่นอนว่าถ้าคุณต้องการล่ามที่ไม่ได้รวมไว้ให้เลือก 2 สำหรับตัวเลือก bundle_files โชคดี!
มิ้นต์

13
โปรดทราบว่า bundle_files 1 ไม่ได้รับการสนับสนุนบน amd64 (py2exe 0.6.9 สำหรับ Python 2.6 อย่างน้อย)
Joril

2
@Pat: การเรียกใช้ py2exe คือ "python setup.py py2exe" ด้วยการผนวก "py2exe" ต่อท้ายโดยอัตโนมัตินั่นหมายความว่าคุณไม่จำเป็นต้องพิมพ์ลงในบรรทัดคำสั่ง
orlade

2
ไม่ว่าปฏิบัติการเดียวที่คุณจำเป็นต้องติดตั้ง Microsoft Visual C รันไทม์ DLL
Kevin Smyth

2
ฉันมีแอปพลิเคชั่นคอนโซลที่ฉันต้องการให้เป็นไฟล์เดียว ฉันต้องแทนที่windows = [{'script': "single.py"}]ด้วยการconsole = ['single.py']ดับเบิลคลิกไฟล์จะเปิดในหน้าต่าง CMD ใน Windows
Jeff B

13

เช่นเดียวกับโปสเตอร์อื่น ๆ ที่กล่าวถึง py2exe จะสร้างไฟล์เรียกทำงาน + บางไลบรารีเพื่อโหลด คุณสามารถมีข้อมูลบางอย่างเพื่อเพิ่มลงในโปรแกรมของคุณ

ขั้นตอนต่อไปคือการใช้โปรแกรมติดตั้งเพื่อจัดทำแพคเกจทั้งหมดนี้ไว้ในโปรแกรมที่ติดตั้งได้ / ไม่สามารถเรียกใช้ได้

ฉันใช้ InnoSetup ( http://www.jrsoftware.org/isinfo.php ) ด้วยความยินดีเป็นเวลาหลายปีและสำหรับโปรแกรมเชิงพาณิชย์ดังนั้นฉันจึงแนะนำให้อย่างเต็มที่


+1 สำหรับการระบุว่าหลังจาก py2exe ยังคงมีสิ่งที่จะต้องแพคเกจ
joaquin

6

ฉันสามารถสร้างไฟล์ exe ไฟล์เดียวโดยมีทรัพยากรทั้งหมดฝังลงในไฟล์ exe ฉันกำลังสร้างบน windows เพื่อที่จะอธิบายบางส่วนของ os.system โทรฉันกำลังใช้

ก่อนอื่นฉันพยายามแปลงภาพทั้งหมดของฉันให้เป็นบิตแมตและจากนั้นไฟล์ข้อมูลทั้งหมดของฉันเป็นสตริงข้อความ แต่สิ่งนี้ทำให้ exe สุดท้ายมีขนาดใหญ่มาก

หลังจาก googleing เป็นเวลาหนึ่งสัปดาห์ฉันก็หาวิธีเปลี่ยนสคริปต์ py2exe เพื่อตอบสนองความต้องการของฉัน

นี่คือลิงค์แพทช์บน sourceforge ที่ฉันส่งโปรดโพสต์ความคิดเห็นเพื่อให้เราสามารถรวมมันไว้ในการกระจายครั้งต่อไป

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

สิ่งนี้อธิบายการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นฉันเพิ่งเพิ่มตัวเลือกใหม่ในบรรทัดการตั้งค่า นี่คือ setup.py ของฉัน

ฉันจะพยายามแสดงความคิดเห็นให้มากที่สุด โปรดทราบว่า setup.py ของฉันมีความซับซ้อนเนื่องจากข้อเท็จจริงที่ว่าฉันเข้าถึงรูปภาพด้วยชื่อไฟล์ ดังนั้นฉันต้องเก็บรายการเพื่อติดตามพวกเขา

นี่เป็นโปรแกรมรักษาหน้าจอที่ฉันต้องการทำ

ฉันใช้ exec เพื่อสร้างการตั้งค่าของฉันในเวลาทำงานมันง่ายกว่าที่จะตัดและวางแบบนั้น

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

ทำให้พังถล่ม

script = py script ฉันต้องการเปลี่ยนเป็น exe

icon_resources = ไอคอนสำหรับ exe

file_resources = ไฟล์ที่ฉันต้องการฝังลงใน exe

other_resources = สตริงที่จะฝังลงใน exe ในกรณีนี้คือรายการไฟล์

options = ตัวเลือก py2exe สำหรับการสร้างทุกอย่างเป็นไฟล์ exe ไฟล์เดียว

bitmap_strings = รายการไฟล์ที่จะรวม

โปรดทราบว่า file_resources ไม่ใช่ตัวเลือกที่ถูกต้องจนกว่าคุณจะแก้ไขไฟล์ py2exe.py ตามที่อธิบายไว้ในลิงค์ด้านบน

ครั้งแรกที่ฉันพยายามโพสต์โค้ดบนเว็บไซต์นี้ถ้าฉันทำผิดอย่าทำให้ฉันรู้สึกแย่

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"

ตกลงนั่นคือสำหรับ setup.py ตอนนี้เวทมนตร์จำเป็นต้องเข้าถึงรูปภาพ ฉันพัฒนาแอพนี้โดยไม่ต้องใช้ py2exe ในใจจากนั้นเพิ่มในภายหลัง ดังนั้นคุณจะเห็นการเข้าถึงสำหรับทั้งสองสถานการณ์ หากไม่พบโฟลเดอร์รูปภาพก็จะพยายามดึงรูปภาพจากทรัพยากร exe รหัสจะอธิบายมัน นี่เป็นส่วนหนึ่งของคลาสสไปรต์ของฉันและใช้ directx แต่คุณสามารถใช้ API ใด ๆ ที่คุณต้องการหรือเพียงแค่เข้าถึงข้อมูลดิบ ไม่สำคัญ

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

คำถามใด ๆ เสียค่าใช้จ่ายในการถาม


ฉันลองใช้วิธีการของคุณแล้วและใช้งานได้ดี แต่ฉันไม่ได้ขีดเส้นใต้และวิธีเพิ่มไฟล์ลงในตัวเลือก file_resurces เพื่อฝังไฟล์ลงในไฟล์. exe ฉันแก้ไขไฟล์ build_exe.py ตามที่คุณพูด แต่เมื่อฉันเข้าไปในไฟล์ setup.py และฉันเขียน\'file_resources': [('txt2.txt')]มันทำให้ฉันมีข้อผิดพลาด (ไฟล์ที่ฉันต้องการฝังใน. exe ชื่อ txt2 และเป็นไฟล์. txt )
VinceLomba

คุณได้พูดคุยเกี่ยวกับวิธีที่คุณแปลงรูปภาพทั้งหมดของคุณเป็นบิตแมตแล้วไฟล์ข้อมูลทั้งหมดของคุณเป็นสตริงข้อความ แม้ว่าคุณจะบอกว่ามันทำให้ exe มีขนาดใหญ่ แต่มันใช้งานได้และถ้าเป็นเช่นนั้นคุณสามารถบอกฉันได้ว่าจะทำอย่างไร ฉันรู้ว่าคำตอบนี้ค่อนข้างเก่า แต่ถ้าคุณสามารถตอบได้ว่าจะได้รับการชื่นชม
Peppa

4

คุณควรสร้างตัวติดตั้งดังที่ได้กล่าวมาแล้ว แม้ว่ามันจะเป็นไปได้ที่จะให้ py2exe รวมทุกอย่างไว้ในไฟล์ปฏิบัติการเดียวโดยการตั้งค่าตัวเลือก bundle_files เป็น 1 และอาร์กิวเมนต์คีย์เวิร์ด zipfile เป็น None แต่ฉันไม่แนะนำสิ่งนี้สำหรับแอปพลิเคชั่น PyGTK

นั่นเป็นเพราะ GTK + พยายามโหลดไฟล์ข้อมูล (ไอเดียธีม ฯลฯ ) จากไดเรกทอรีที่โหลดมา ดังนั้นคุณต้องตรวจสอบให้แน่ใจว่าไดเรกทอรีของแฟ้มที่ปฏิบัติการของคุณนั้นมีไลบรารีที่ GTK + ใช้และ lib ไดเรกทอรีแชร์และอื่น ๆ จากการติดตั้ง GTK + ของคุณ ไม่เช่นนั้นคุณจะพบปัญหาในการเรียกใช้แอปพลิเคชันของคุณบนเครื่องที่ไม่ได้ติดตั้ง GTK + ทั้งระบบ

สำหรับรายละเอียดเพิ่มเติมอ่านของฉันคู่มือ py2exe สำหรับการใช้งาน นอกจากนี้ยังอธิบายถึงวิธีการรวมทุกอย่าง แต่ GTK +


1

ฉันบอกว่าbbfreezeจะสร้างไฟล์เดียว. EXE และใหม่กว่า py2exe


3
เท่าที่ฉันสามารถเข้าใจ bbfreeze ไม่ผลิตไฟล์ปฏิบัติการเดี่ยว คุณบันทึกเอกสารคำตอบของคุณได้ไหม
joaquin

-2

ฉันเพิ่งใช้ py2exe เพื่อสร้างไฟล์ปฏิบัติการสำหรับโพสต์รีวิวเพื่อส่งรีวิวไปยัง ReviewBoard

นี่คือ setup.py ฉันใช้

from distutils.core import setup
import py2exe

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

มันสร้างไดเรกทอรีที่มีไฟล์ exe และห้องสมุดที่จำเป็น ฉันไม่คิดว่าเป็นไปได้ที่จะใช้ py2exe เพื่อรับไฟล์. exe เพียงไฟล์เดียว หากคุณต้องการให้คุณต้องใช้ py2exe ก่อนจากนั้นใช้โปรแกรมติดตั้งบางรูปแบบเพื่อให้สามารถเรียกใช้งานขั้นสุดท้ายได้

สิ่งหนึ่งที่ต้องระวังคือไฟล์ไข่ที่คุณใช้ในแอปพลิเคชันของคุณจะต้องทำการคลายซิปมิฉะนั้น py2exe จะไม่สามารถรวมไว้ได้ สิ่งนี้ครอบคลุมอยู่ในเอกสาร py2exe


-2

ลอง c_x ค้าง ไว้มันสามารถสร้าง standalone ที่ดีได้


cx_Freeze ไม่สามารถสร้างไฟล์ปฏิบัติการแบบสแตนด์อโลนในความเป็นจริงเอกสารประกอบสำหรับ cx_Freeze ที่buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… กล่าวว่า "cx_Freeze ไม่สนับสนุนการสร้างไฟล์เดียว exe ไลบรารีสำหรับแอปพลิเคชันของคุณจะถูกฝังอยู่ในไฟล์เรียกทำงานไฟล์เดียว " สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ปฏิบัติการแบบสแตนด์อโลนใน cx_Freeze ให้ไปที่เอกสาร ( buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/ ...... ) และไปที่หัวข้อ 4.5
Peppa

-6

ไม่มันไม่ได้ทำให้คุณสามารถเรียกใช้ไฟล์ได้เพียงไฟล์เดียว แต่คุณมีไดเรกทอรีที่มีทุกอย่างที่คุณต้องการสำหรับการใช้งานโปรแกรมรวมถึงไฟล์ exe

ฉันเพิ่งเขียนsetup.pyนี้วันนี้ python setup.py py2exeคุณจะต้องเรียกใช้


1
มันไม่ถูกต้อง ด้วยตัวเลือกที่ถูกต้องคุณจะได้รับหนึ่งไฟล์แบบสแตนด์อโลน
trevorKirkby

@Torsten Marek ... ลิงก์ไปยัง setup.py ของคุณตายแล้ว โดยเฉพาะอย่างยิ่ง .. สองรายการแรกที่ได้รับการส่งเสริมซ้ำเพื่อโฆษณาเชิงพาณิชย์ ครั้งที่สามมันจบลงที่นี่ที่จุดจบของอินเทอร์เน็ต
ZF007
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.