py2exe - gera um único arquivo executável


141

Eu pensei ter ouvido falar que o py2exe era capaz de fazer isso, mas nunca entendi. Alguém já fez isso com sucesso? Posso ver seu arquivo setup.py e quais opções de linha de comando você usou?

Basicamente, estou pensando em me dar um único arquivo executável que faz algo como descompacta-se em talvez / temp e é executado.


Isso se aplica ao Python 3 ou a versões posteriores ao python 2?
Vincent

Respostas:


105

PyInstaller criará um único arquivo .exe sem dependências; use a --onefileopção Ele faz isso compactando todas as bibliotecas compartilhadas necessárias no executável e descompactando-as antes da execução, assim como você descreve (EDIT: py2exe também possui esse recurso, consulte a resposta da minty )

Eu uso a versão do PyInstaller do svn, pois a versão mais recente (1.3) está um pouco desatualizada. Ele está funcionando muito bem para um aplicativo que depende de PyQt, PyQwt, numpy, scipy e mais alguns.


5
Descobri que o py2exe funcionava muito melhor do que o pyInstaller, quando você usa ovos. A resposta de minty é a solução.
gbjbaanb 30/07/2009

Observe que, a partir da versão 1.4, o PyInstaller não oferece suporte ao Python 2.6 ou superior no Windows
Joril 9/11

2
Agora estou usando a versão 1.5.1 e funciona com o Python 2.7.2.
oob

1
py2exe pode criar um único arquivo executável se você especificar alguns argumentos no programa de compilação. O py2exe possui um tutorial on-line para executáveis ​​de arquivo único.
usar o seguinte código

2
Ponto de vista objetivo: Não vejo como essa é uma resposta aceitável, pois não trata da questão de criar um único arquivo exe com o py2exe. (No entanto, esta é uma resposta útil, é claro.)
Jonathan Komar

171

A maneira de fazer isso usando py2exe é usar a opção bundle_files no seu arquivo setup.py. Para um único arquivo, você deseja definir bundle_files1, compressedcomo True e definir a opção zipfile como Nenhum. Dessa forma, ele cria um arquivo compactado para facilitar a distribuição.

Aqui está uma descrição mais completa da opção bundle_file citada diretamente no site py2exe *

Usando "bundle_files" e "zipfile"

Uma maneira mais fácil (e melhor) de criar executáveis ​​de arquivo único é definir bundle_files como 1 ou 2 e definir zipfile como None. Essa abordagem não requer a extração de arquivos para um local temporário, o que proporciona uma inicialização muito mais rápida do programa.

Os valores válidos para bundle_files são:

  • 3 (padrão) não agrupam
  • 2 agrupa tudo, menos o intérprete Python
  • 1 agrupa tudo, incluindo o interpretador Python

Se zipfile estiver definido como None, os arquivos serão agrupados no executável em vez de library.zip.

Aqui está um exemplo de 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
Certifique-se de que você deseja que apenas o intérprete não seja incluído, escolha 2 para a opção bundle_files. Boa sorte!
Minty

13
Por favor note que bundle_files 1 não é suportado em amd64 (py2exe 0.6.9 para Python 2.6, pelo menos)
Joril

2
@ Pat: A chamada para executar py2exe é "python setup.py py2exe". Ao anexar automaticamente o "py2exe" no final, significa apenas que você não precisa digitá-lo na linha de comando.
orlade

2
Não é exatamente um único executável, como você precisa instalar o Visual C runtime DLL Microsoft .
Kevin Smyth

2
Eu tinha um aplicativo de console que queria ter como um único executável. Eu tive que substituir windows = [{'script': "single.py"}]com console = ['single.py']um clique duplo para que o arquivo fosse aberto em uma janela CMD no Windows.
9134 Jeff B

13

Como o outro pôster mencionado, py2exe, irá gerar um executável + algumas bibliotecas para carregar. Você também pode ter alguns dados para adicionar ao seu programa.

O próximo passo é usar um instalador, empacotar tudo isso em um programa instalável / não instalável fácil de usar.

Eu uso o InnoSetup ( http://www.jrsoftware.org/isinfo.php ) com prazer há vários anos e em programas comerciais, por isso recomendo vivamente.


+1 por indicar que, depois do py2exe, ainda há coisas a serem empacotadas.
Joaquin

6

Consegui criar um único arquivo exe com todos os recursos incorporados no exe. Estou construindo nas janelas. de modo a explicar algumas das chamadas do os.system que estou usando.

Primeiro, tentei converter todas as minhas imagens em bitmats e depois todos os meus arquivos de dados em cadeias de texto. mas isso fez com que o exe final fosse muito, muito grande.

Depois de pesquisar no google por uma semana, descobri como alterar o script py2exe para atender às minhas necessidades.

aqui está o link do patch no sourceforge que enviei, por favor, poste comentários para que possamos incluí-lo na próxima distribuição.

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

isso explica todas as alterações feitas, simplesmente adicionei uma nova opção à linha de instalação. aqui está o meu setup.py.

vou tentar comentar da melhor maneira possível. Saiba que meu setup.py é complexo, devido ao fato de eu acessar as imagens por nome de arquivo. então devo armazenar uma lista para acompanhá-los.

isso é de um protetor de tela que eu estava tentando criar.

Eu uso exec para gerar minha configuração em tempo de execução, é mais fácil cortar e colar assim.

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

demolir

script = py script eu quero virar para um exe

icon_resources = o ícone para o exe

file_resources = arquivos que eu quero incorporar no exe

other_resources = uma string para incorporar no exe, neste caso uma lista de arquivos.

options = py2exe opções para criar tudo em um arquivo exe

bitmap_strings = uma lista de arquivos para incluir

Observe que file_resources não é uma opção válida até você editar o arquivo py2exe.py, conforme descrito no link acima.

primeira vez que tentei postar código neste site, se eu entendi errado, não me chame.

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, é isso para o setup.py agora a mágica necessária para acessar as imagens. Eu desenvolvi este aplicativo sem py2exe em mente e o adicionei mais tarde. então você verá acesso para ambas as situações. se a pasta da imagem não puder ser encontrada, ela tenta extrair as imagens dos recursos exe. o código irá explicar isso. isso faz parte da minha classe de sprite e usa um directx. mas você pode usar qualquer API que desejar ou apenas acessar os dados brutos. não importa.

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

Qualquer pergunta ficou livre para perguntar.


Eu tentei o seu método e ele funciona bem, mas não entendo e como adicionar arquivo à opção file_resurces para embloquear algum arquivo no .exe. Eu modifiquei o arquivo build_exe.py como você disse, mas quando eu vou para o arquivo setup.py e o escrevo \'file_resources': [('txt2.txt')], ocorre um erro (o arquivo que eu quero inserir no meu .exe é denominado txt2 e é um arquivo .txt )
VinceLomba

Você falou sobre como converter todas as suas imagens em bitmats e, em seguida, todos os seus arquivos de dados em cadeias de texto. Mesmo que você tenha dito que o exe é grande, isso funciona e, se sim, você pode me dizer como fazer isso? Eu sei que esta resposta é bastante antiga, mas se você puder responder, isso será apreciado.
Peppa

4

Você deve criar um instalador, como mencionado anteriormente. Embora também seja possível permitir que o py2exe agrupe tudo em um único executável, definindo a opção bundle_files como 1 e o argumento da palavra-chave zipfile como None, não recomendo isso para aplicativos PyGTK.

Isso ocorre porque o GTK + tenta carregar seus arquivos de dados (locais, temas etc.) do diretório em que foi carregado. Portanto, você deve garantir que o diretório do seu executável contenha também as bibliotecas usadas pelo GTK + e os diretórios lib, share e etc da sua instalação do GTK +. Caso contrário, você terá problemas ao executar seu aplicativo em uma máquina em que o GTK + não esteja instalado em todo o sistema.

Para mais detalhes, leia meu guia sobre py2exe para aplicativos PyGTK . Ele também explica como agrupar tudo, exceto o GTK +.


1

Disseram-me que o bbfreeze criará um único arquivo .EXE e é mais recente que o py2exe.


3
Tanto quanto eu posso entender, o bbfreeze não produz executáveis ​​de arquivo único. Você poderia documentar sua resposta?
Joaquin

-2

Recentemente, usei o py2exe para criar um executável para pós-revisão para enviar revisões ao ReviewBoard.

Esse foi o setup.py que eu usei

from distutils.core import setup
import py2exe

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

Ele criou um diretório que contém o arquivo exe e as bibliotecas necessárias. Eu não acho que é possível usar o py2exe para obter apenas um único arquivo .exe. Se você precisar, primeiro precisará usar o py2exe e, em seguida, usar alguma forma de instalador para tornar o executável final.

Uma coisa para cuidar é que todos os arquivos egg que você usa no seu aplicativo precisam ser descompactados, caso contrário, o py2exe não poderá incluí-los. Isso é abordado nos documentos py2exe.


-2

tente congelar c_x , pode criar um bom standalone


O cx_Freeze não pode criar um executável independente; de ​​fato, a documentação para o cx_Freeze em buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… diz: "O cx_Freeze não suporta a criação de um único arquivo exe, onde todos os as bibliotecas do seu aplicativo são incorporadas em um arquivo executável ". Para obter mais detalhes sobre os executáveis ​​independentes no cx_Freeze, vá para a documentação ( buildmedia.readthedocs.org/media/pdf/cx-freeze/latest/… ) e vá para a seção 4.5.
Peppa

-6

Não, ele não fornece um único executável no sentido de que você só tem um arquivo depois - mas você tem um diretório que contém tudo o que você precisa para executar seu programa, incluindo um arquivo exe.

Acabei de escrever este arquivo setup.py hoje. Você só precisa invocar python setup.py py2exe.


1
Isto não é exato. Com as opções corretas, você pode obter um arquivo independente.
trevorKirkby

@Torsten Marek ... o link para o seu setup.py está morto. Em particular .. os dois primeiros redirecionamentos acabam promovendo coisas comerciais. A terceira vez termina aqui no beco sem saída da internet.
ZF007
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.