py2exe - сгенерировать один исполняемый файл
Мне казалось, я слышал, что py2exe смог это сделать, но я так и не понял. Кто-нибудь успешно это сделал? Могу ли я посмотреть ваш файл setup.py и какие параметры командной строки вы использовали?
В принципе, я думаю о том, что это даст мне один исполняемый файл, который выполняет что-то вроде самораспаковки в maybe / temp и запускается.
Переведено автоматически
Ответ 1
Способ сделать это с помощью py2exe - использовать опцию bundle_files в вашем файле setup.py. Для одного файла вам нужно будет установить bundle_files
значение 1, compressed
значение True и установить для параметра zipfile значение None . Таким образом, создается один сжатый файл для упрощения распространения.
Вот более полное описание параметра bundle_file , приведенное непосредственно с сайта py2exe*
Используя "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,
)
Ответ 2
PyInstaller создаст один .exe файл без зависимостей; используйте --onefile
опцию. Это делается путем упаковки всех необходимых общих библиотек в исполняемый файл и распаковки их перед запуском, как вы описали (РЕДАКТИРОВАТЬ: py2exe также имеет эту функцию, см. Ответ minty )
Я использую версию PyInstaller из svn, поскольку последняя версия (1.3) несколько устарела. Это действительно хорошо работает для приложения, которое зависит от PyQt, PyQwt, numpy, scipy и некоторых других.
Ответ 3
Как упоминалось в другом постере, py2exe
сгенерирует исполняемый файл + некоторые библиотеки для загрузки. У вас также могут быть некоторые данные для добавления в вашу программу.
Next step is to use an installer, to package all this into one easy-to-use installable/unistallable program.
I have used InnoSetup with delight for several years and for commercial programs, so I heartily recommend it.
Ответ 4
I've been able to create a single exe file with all resources embeded into the exe.
I'm building on windows. so that will explain some of the os.system calls i'm using.
First I tried converting all my images into bitmats and then all my data files into text strings.
but this caused the final exe to be very very large.
After googleing for a week i figured out how to alter py2exe script to meet my needs.
here is the patch link on sourceforge i submitted, please post comments so we can get it included in
the next distribution.
http://sourceforge.net/tracker/index.php?func=detail&aid=3334760&group_id=15583&atid=315583
this explanes all the changes made, i've simply added a new option to the setup line.
here is my setup.py.
i'll try to comment it as best I can.
Please know that my setup.py is complex do to the fact that i'm access the images by filename.
so I must store a list to keep track of them.
this is from a want-to-b screen saver I was trying to make.
I use exec to generate my setup at run time, its easyer to cut and paste like that.
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])
breakdown
script = py script i want to turn to an exe
icon_resources = the icon for the exe
file_resources = files I want to embed into the exe
other_resources = a string to embed into the exe, in this case a file list.
options = py2exe options for creating everything into one exe file
bitmap_strings = a list of files to include
Please note that file_resources is not a valid option untill you edit your py2exe.py file as described in the link above.
first time i've tried to post code on this site, if I get it wrong don't flame me.
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, thats it for the setup.py
now the magic needed access the images.
I developed this app without py2exe in mind then added it later.
so you'll see access for both situations. if the image folder can't be found
it tries to pull the images from the exe resources. the code will explain it.
this is part of my sprite class and it uses a directx. but you can use any api you want or just access the raw data.
doesn't matter.
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!")
Any questions fell free to ask.