py2exe - 生成单个可执行文件

Gre*_*reg 138 python packaging py2exe

我以为我听说py2exe能够做到这一点,但我从未弄明白.有没有人成功完成这个?我可以看到你的setup.py文件,以及你使用的命令行选项吗?

基本上我正在考虑给它一个可执行文件,它可以像解压缩/ temp和运行一样.

min*_*nty 170

使用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,
)
Run Code Online (Sandbox Code Playgroud)

  • 请注意amd64不支持bundle_files 1(Python 2.6至少为py2exe 0.6.9) (13认同)
  • 当然,如果您只想要未捆绑的解释器,请为bundle_files选项选择2.祝好运! (5认同)
  • 对于Python 2.7仍然如此. (5认同)
  • `sys.argv.append('py2exe')` 行是怎么回事?我不需要它来工作。 (2认同)
  • @Pat:运行py2exe的调用是"python setup.py py2exe".通过在末尾自动附加"py2exe",它只意味着您不必在命令行输入它. (2认同)
  • 不是一个可执行文件,因为您需要[安装Microsoft Visual C运行时DLL](http://www.py2exe.org/index.cgi/Tutorial#A5.ProvidingtheMicrosoftVisualCruntimeDLL). (2认同)
  • 我有一个控制台应用程序,我希望将其作为单个可执行文件.我不得不用`console = ['single.py']`替换`windows = [{'script':"single.py"}]`所以双击该文件将在Windows的CMD窗口中打开. (2认同)
  • @ Joril评论6年后仍然 - "错误:win64上尚未支持bundle-files 1" (2认同)

dF.*_*dF. 102

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

我使用svn中的PyInstaller版本,因为最新版本(1.3)有点过时了.对于一个依赖于PyQt,PyQwt,numpy,scipy等等的应用来说,它的效果非常好.

  • 当你使用鸡蛋时,我发现py2exe比pyInstaller好多了.薄荷的答案是解决方案. (5认同)
  • 我现在使用的是1.5.1版本,它适用于Python 2.7.2. (2认同)
  • 客观观点:我看不出这是一个可以接受的答案,因为它没有解决使用py2exe创建单个exe文件的问题。(不过,这当然是一个有用的答案。) (2认同)

Phi*_*e F 13

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

下一步是使用安装程序将所有这些打包成一个易于使用的可安装/不可操作程序.

我已经使用了InnoSetup(http://www.jrsoftware.org/isinfo.php)多年的喜悦和商业节目,所以我衷心推荐它.


小智 7

我已经能够创建一个 exe 文件,其中所有资源都嵌入到 exe 中。我在窗户上建造。这样就可以解释我正在使用的一些 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])
Run Code Online (Sandbox Code Playgroud)

分解

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"
Run Code Online (Sandbox Code Playgroud)

好的,这就是 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!")
Run Code Online (Sandbox Code Playgroud)

任何问题都可以问。