понедельник, 17 августа 2015 г.

“Сборка” Python скрипта в один exe файл


Все мы знаем, что пайтон интерпретируемый язык и получить настоящий скомпилированный exe файл - нет возможности. Однако, есть такие проекты как: py2exe или cx_freeze, которые, анализируя код приложения, собирают все зависимые библиотеки и сам интерпретатор в отдельной папке, и создают запускающий exe файл. Этот exe файл при запуске подготовит окружение для нашего приложения, запустит интерпретатор python и уже в нем - наше приложение. После работ утилит py2exe или cx_freeze у нас всегда появляются куча dll и др. файлов.


Так что же сделать для получения одного exe файла, вместо кучи файлов?


Будем считать, что у нас уже есть папка (dist) с зависимыми файлами, после прогона py2exe или cx_freeze.


  • Первым делом, чистим за утилитами py2exe или cx_freeze библиотеки и файлы, которые гарантированно не будут использоваться. (например: w9xpopen.exe).Таким образом, уменьшаем размер нашего будущего exe файла и скорость его загрузки.
  • Далее, упаковываем архиватором 7zip (если у Вас его нет, то скорее качаем с официального сайта: www.7-zip.org) папку (dist) со всеми файлами.


Все параметры упаковки лучше запомнить, так как далее они понадобятся.
Я упаковку делаю из командной строки поэтому и запомнить просто :)
Например: C:\7-Zip\7z.exe a -r -t7z -m1=LZMA dist.7z dist\*.*


Далее начинается темная магия, которой порой, пользуются всякие недалекие вирусописатели.


Идем на сайт http://7zsfx.info/ru/ и скачиваем специальный модифицированный модуль (например: 7zsd.sfx) для распаковки нашего приложения “по тихому” и запуску одного из файлов внутри архива. Модуль должен быть с поддержкой именно того сжатия, которое применяем, в моем случае это LZMA, a есть еще лучше - LZMA2)


Далее готовим файл настройки для модуля 7zsd.sfx:
(config.txt)

;!@Install@!UTF-8!
RunProgram="наш_запускатор.exe /s"
GUIMode="2"
;!@InstallEnd@!


Главная строчка здесь это: RunProgram с ключем /s - говорит, что после распаковки запустить “по тихому” (/s) файл из архива.


Следующим шагом идем в командную строку и делаем следующие:
copy /b 7zsd.sfx + config.txt + dist.7z alone.exe


Итогом получаем один exe (alone.exe) файл, который на самом деле является файлом состоящем из трех частей. Распаковщика (7zsd.sfx), конфига к нему (config.txt) и нашего дистрибутива (dist.7z).


После запуска, произойдет следующее: во временной директории (TEMP) будет развернут наш дистрибутив и автоматом запустится файл из него (alone.exe). Распакованные файлы останутся лежать в  (TEMP), если оно нам не надо, то в конфигурационном файле надо добавить ключик delete=директория.
А вообще рекомендую посмотреть справку по модулю 7zsfx на официальном сайте:



Как поменять иконку приложения и описание программы?

Для этого воспользуемся программой Resource Hacker
Процесс простой, описывать думаю нет смысла.


Что дальше?

Все использованные программы могут работать из командной строки и легко принимают разные параметры. Поэтому можно легко сделать bat файл со всем этим процессом (компилятор_всея_пайтон.bat)  и запускать по мере необходимости.


Оптимизация: скорость, размер, можно попробовать воспользоваться UPX
http://upx.sourceforge.net/ для сжатия. Может оно что-то и даст.


Приятные бонусы.

Бесплатным бонусом идет возможность шифрования кода нашего приложения  и установка пароля на запуск приложения. Но… Ниже о безопасности кода.


Не могу промолчать про минусы.
  1. Возможно, некоторые антивирусы будут ругаться.
  2. Исходный код можно все равно перехватить, например, подсмотрев его во время распаковки архива во временную директорию.
  3. Медленный запуск приложения. (Можно победить подбором параметров сжатия и удалением мусорных файлов из дистрибутива) (А на SSD, так вообще не заметно:) )  


Второй пункт можно чуть улучшить, если использовать распаковку на виртуальный диск в памяти, который предварительно надо создать. Это даст еще 2 очка к безопасности кода. :) Но защита все равно очень слабенькая…