py2exe-生成单个可执行文件


141

我以为我听说py2exe可以做到这一点,但我从来没有想过。有人成功做到了吗?我可以看到您的setup.py文件以及使用的哪些命令行选项吗?

基本上,我正在考虑给它提供一个可执行文件,该文件可执行将自身解压缩到/ temp并运行的操作。


这是否适用于Python 3或python 2之后的版本?
文森特

Answers:


105

PyInstaller将创建一个没有依赖关系的.exe文件;使用该--onefile选项。它通过将所有需要的共享库打包到可执行文件中,并在运行之前解压缩它们来完成此操作,正如您所描述的那样(编辑:py2exe也具有此功能,请参见minty的答案

我使用的是svn的PyInstaller版本,因为最新版本(1.3)有点过时了。对于依赖于PyQt,PyQwt,numpy,scipy等应用程序的应用程序来说,它的运行情况非常好。


5
当您使用鸡蛋时,我发现py2exe比pyInstaller更好。minty的答案是解决方案。
gbjbaanb 2009年

请注意,从1.4版开始,PyInstaller在Windows上不支持Python 2.6+
Joril 2011年

2
我现在使用的是1.5.1版,并且可以在Python 2.7.2中使用。
oob 2012年

1
如果在编译器程序中指定一些参数,py2exe可以创建一个文件可执行文件。py2exe具有在线单个文件可执行文件的教程。
trevorKirkby 2013年

2
客观观点:我看不出这是一个可以接受的答案,因为它没有解决使用py2exe创建单个exe文件的问题。(不过,这当然是一个有用的答案。)
乔纳森·科玛

171

使用py2exe进行此操作的方法是在setup.py文件中使用bundle_files选项。对于单个文件,您将需要设置bundle_files为1,compressed为True,并将zipfile选项设置为None。这样,它会创建一个压缩文件以便于分发。

这是直接从py2exe网站引用的bundle_file选项的更完整说明*

使用“ bundle_files”和“ zipfile”

创建单文件可执行文件的一种更简单(更好)的方法是将bundle_files设置为1或2,并将zipfile设置为None。这种方法不需要将文件提取到一个临时位置,从而可以更快地启动程序。

bundle_files的有效值为:

  • 3(默认)不捆绑
  • 2捆绑除Python解释器以外的所有内容
  • 1捆绑一切,包括Python解释器

如果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
当然,如果您只希望不捆绑解释器,则为bundle_files选项选择2。祝好运!
薄荷

13
请注意,amd64不支持bundle_files 1(至少对于python 2.6为py2exe 0.6.9)
Joril 2011年

2
@Pat:运行py2exe的调用是“ python setup.py py2exe”。通过在末尾自动附加“ py2exe”,这意味着您不必在命令行中键入它。
Orlade

2
不完全是一个可执行文件,因为您需要安装Microsoft Visual C运行时DLL
凯文·史密斯

2
我有一个控制台应用程序,希望将其作为单个可执行文件包含。我必须替换windows = [{'script': "single.py"}]console = ['single.py']双击文件才能在Windows的CMD窗口中打开。
杰夫·B

13

就像其他海报提到的那样,py2exe将生成一个可执行文件和一些要加载的库。您还可以将一些数据添加到程序中。

下一步是使用安装程序,将所有这些程序打包到一个易于使用的可安装/不可安装程序中。

我使用InnoSetup(http://www.jrsoftware.org/isinfo.php)已经有好几年了,并且用于商业程序,所以我衷心推荐它。


+1表示py2exe之后仍然有东西要打包。
joaquin 2011年

6

我已经能够将所有资源嵌入到exe中来创建一个exe文件。我在Windows上构建。这样就可以解释我正在使用的os.system调用。

首先,我尝试将所有图像转换为位垫,然后将所有数据文件转换为文本字符串。但这导致最终exe变得非常大。

谷歌搜索一周后,我想出了如何更改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])

分解

脚本= PY脚本,我想转向一个EXE

icon_resources = exe的图标

file_resources =我要嵌入exe的文件

other_resources =要嵌入到exe中的字符串,在这种情况下为文件列表。

options = py2exe用于将所有内容创建到一个exe文件中的选项

bitmap_strings =要包含的文件列表

请注意,只有按照上述链接中所述编辑py2exe.py文件后,file_resources才是有效选项。

第一次尝试在此站点上发布代码,如果我弄错了,请不要解雇我。

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资源中提取图像。代码将对此进行解释。这是我的Sprite类的一部分,它使用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 2015年

您谈到了如何将所有图像转换为位垫,然后将所有数据文件转换为文本字符串。即使您说过使exe变大,它也可以工作,如果可以,您能否告诉我该怎么做?我知道这个答案已经很老了,但是如果您能回答,将不胜感激。
佩佩

4

如前所述,您应该创建一个安装程序。即使也可以通过将bundle_files选项设置为1并将zipfile关键字参数设置为None来让py2exe将所有内容捆绑到一个可执行文件中,但我不建议PyGTK应用程序使用此方法。

这是因为GTK +试图从其加载目录中加载其数据文件(本地,主题等)。因此,您必须确保可执行文件的目录还包含GTK +使用的库以及GTK +安装中的目录lib,share等。否则,您将在未在全系统范围内安装GTK +的计算机上运行应用程序时遇到问题。

有关更多详细信息,请阅读我的PyGTK应用程序py2exe指南。它还说明了如何捆绑除GTK +之外的所有内容。


1

我被告知bbfreeze将创建一个文件.EXE,并且比py2exe更新。


3
据我了解,bbfreeze不会生成单文件可执行文件。你能证明你的答案吗?
joaquin

-1

尝试 c_x Frozen 它可以创建一个很好的独立版本


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

-2

我最近使用py2exe创建了一个用于后期审阅的可执行文件,用于将审阅发送到ReviewBoard。

这是我使用的setup.py

from distutils.core import setup
import py2exe

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

它创建了一个目录,其中包含exe文件和所需的库。我认为无法使用py2exe来获取单个.exe文件。如果需要,首先需要使用py2exe,然后使用某种形式的安装程序来制作最终的可执行文件。

需要注意的一件事是,您在应用程序中使用的任何egg文件都需要解压缩,否则py2exe不能包含它们。py2exe文档中对此进行了介绍。


-6

不,就您以后只有一个文件的意义而言,它没有给您单个可执行文件-但您有一个目录,其中包含运行程序所需的所有文件,包括exe文件。

我今天才写了这个setup.py。您只需要调用python setup.py py2exe


1
这是不准确的。使用正确的选项,您可以获得一个独立文件。
trevorKirkby 2013年

@Torsten Marek ...指向setup.py的链接已死。尤其是前两个重新设计最终会推广商品。第三次是结束这里在互联网的死胡同。
ZF007
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.