【问题标题】:py2exe - generate single executable filepy2exe - 生成单个可执行文件
【发布时间】:2010-09-11 21:06:08
【问题描述】:

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

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

【问题讨论】:

  • 这适用于 Python 3 还是 Python 2 之后的版本?

标签: python packaging py2exe


【解决方案1】:

正如另一张海报提到的,py2exe,将生成一个可执行文件 + 一些要加载的库。您还可以将一些数据添加到您的程序中。

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

InnoSetup 多年来我一直很高兴地使用它并用于商业程序,所以我衷心推荐它。

【讨论】:

  • +1 表示py2exe之后还有东西要打包。
【解决方案2】:

试试 c_x freeze 它可以创建一个很好的独立

【讨论】:

【解决方案3】:

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

这里是直接引用自py2exe site* 的 bundle_file 选项的更完整描述

使用“bundle_files”和“zipfile”

更简单(更好)的创建方式 单文件可执行文件是设置 bundle_files 为 1 或 2,并设置 zipfile 为无。这种方法确实 不需要将文件提取到 临时位置,它提供 程序启动速度更快。

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

【讨论】:

  • 如果你只想要解释器而不是捆绑,那么为 bundle_files 选项选择 2。祝你好运!
  • 请注意,amd64 不支持 bundle_files 1(至少 Python 2.6 的 py2exe 0.6.9)
  • sys.argv.append('py2exe') 行是怎么回事?我不需要它来工作。
  • 不完全是一个可执行文件,你需要install the Microsoft Visual C runtime DLL。
  • 我有一个控制台应用程序,我想将其作为单个可执行文件。我不得不将windows = [{'script': "single.py"}] 替换为console = ['single.py'],这样双击该文件就会在Windows 的CMD 窗口中打开。
【解决方案4】:

PyInstaller 将创建一个没有依赖关系的单个 .exe 文件;使用--onefile 选项。它通过将所有需要的共享库打包到可执行文件中来做到这一点,并在运行之前将它们解包,就像您描述的那样(编辑:py2exe 也具有此功能,请参阅minty's answer)

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

【讨论】:

  • 当你使用鸡蛋时,我发现 py2exe 比 pyInstaller 工作得更好。 minty 的答案就是解决方案。
  • 请注意,从 1.4 版开始,PyInstaller 不支持 Windows 上的 Python 2.6+
  • 我现在使用的是 1.5.1 版本,它适用于 Python 2.7.2。
  • py2exe 如果您在编译器程序中指定一些参数,则可以创建单个文件可执行文件。 py2exe 有一个在线单文件可执行文件的教程。
  • 客观观点:我看不出这是一个可以接受的答案,因为它没有解决使用 py2exe 创建单个 exe 文件的问题。 (尽管如此,这当然是一个有用的答案。)
【解决方案5】:

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

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

在谷歌搜索一周后,我想出了如何更改 py2exe 脚本以满足我的需求。

这是我提交的 sourceforge 上的补丁链接,请发布 cmets 以便我们将其包含在 下一次分发。

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 脚本我想转成一个 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 资源中提取图像。代码将解释它。 这是我的精灵类的一部分,它使用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 文件)
  • 您谈到了如何将所有图像转换为位图,然后将所有数据文件转换为文本字符串。即使您说它会使 exe 变大,这是否有效,如果可以,您能告诉我该怎么做吗?我知道这个答案已经很老了,但如果你能回复,将不胜感激。
【解决方案6】:

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

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

更多详情请阅读我的guide to py2exe for PyGTK applications。它还解释了如何捆绑所有东西,但 GTK+ 除外。

【讨论】:

    【解决方案7】:

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

    【讨论】:

    • 据我所知,bbfreeze 不会生成单文件可执行文件。你能记录下你的答案吗?
    【解决方案8】:

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

    这是我使用的 setup.py

    from distutils.core import setup
    import py2exe
    
    setup(console=['post-review'])
    

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

    需要注意的一点是,您在应用程序中使用的任何 egg 文件都需要解压缩,否则 py2exe 无法包含它们。这在 py2exe 文档中有介绍。

    【讨论】:

      【解决方案9】:

      不,它不会为您提供一个可执行文件,因为您之后只有一个文件 - 但您有一个目录,其中包含运行程序所需的所有内容,包括一个 exe 文件。

      我今天刚刚写了this setup.py。你只需要调用python setup.py py2exe。

      【讨论】:

      • 这不准确。使用正确的选项,您可以获得一个独立的文件。
      • @Torsten Marek... setup.py 的链接已失效。特别是……前两个重定向最终促进了商业活动。第三次在互联网的尽头here结束。
      猜你喜欢
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 2013-11-20
      相关资源
      最近更新 更多