Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 30, 2015 10:49:18

key
Зарегистрирован: 2015-09-30
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

Задача: создать один exe, содержащий в себе интерпретатор питоновский + некоторый набор файлов.
Тобишь, чтобы юзер запускал программу не имея интерпретатора питоновского и в гуи была одна кнопка “сделать хорошо”, по нажатию на которую будет идти распаковка файлов (зашитых внутрь исполняемой программы).

Вопрос по большей части интересует каким образом можно зашить файлы, с которыми придется работать, внутрь исполняемой программы?

Отредактировано key (Сен. 30, 2015 10:50:27)

Офлайн

#2 Сен. 30, 2015 12:47:12

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

модули cx_freeze, PyInstaller



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Сен. 30, 2015 14:31:04

key
Зарегистрирован: 2015-09-30
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

один вопрос, как потом обращаться к файлу зашитому в этот экзешник?

Офлайн

#4 Сен. 30, 2015 14:38:06

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

cx_freeze/PyInstaller сами всё распакуют и запустят

Офлайн

#5 Сен. 30, 2015 21:41:03

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

Shaman
cx_freeze/PyInstaller сами всё распакуют и запустят
Наверное не совсем так?
cx_freeze Делают запускаемый exe.
А автор топика похоже хочет инсталятор с кнопкой “сделать хорошо”. Один раз распаковка и потом чтобы все работало хорошо. Тогда http://nsis.sourceforge.net/Main_Page или аналогичные вещи.



Офлайн

#6 Сен. 30, 2015 22:05:46

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

doza_and
Может и так. Чего именно хочет автор не совсем понятно.

Офлайн

#7 Сен. 30, 2015 22:15:36

key
Зарегистрирован: 2015-09-30
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

Наверное не правильно выразился, задача стоит в написании архиватора/разархиватора.
Пример есть такие файлы: 1.jpg, 2.txt, 3.png, собираем все в один файл files.archive, теперь собираем питоновское приложение как один program.exe и запаковываем туда files.archive.
Что мы имеем? Один program.exe файл, в котором питоновский интерпретатор + архивный файл (очень важно один файл, а не несколько), далее нажимаем кнопку “распаковать” и файлы 1.jpg, 2.txt, 3.png распаковываются.

Это своего рода патчер, который ищет директорию, где установлена игра и заменяем там файлы и закрывает запущенное приложение игры, чтобы заменить полностью. Текущие проблемы:
1. если давать в .rar или zip и т.д., то не у всех он есть (да и такие бывают);
2. не могут найти папку с игрой;
3. не понимают, что сперва надо закрыть игру, а потом патчить.
и т.д.

Очень важно дать один .exe, который “сделает как надо все сам”, игроку не надо знать, где игра, что заменять, закрывать и т.д.

Какие есть предложения?

Отредактировано key (Сен. 30, 2015 22:50:43)

Офлайн

#8 Окт. 1, 2015 09:25:48

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Зашить в исполняемую программу дополнительный файл (файлы)

Предлагаю не делать кнопку “Сделать хорошо”. Ума не приложу как это просто сделать (может html приложить).
Если посмотрите формат исполняемого модуля, то данные можно просто записать в конец исполняемого файла. А при распаковке будете делать то что вам нужно. Обычно эту задачу решает инсталятор (и генератор дистрибутивов). Так что есть резон смотреть на данную мною вам ссылку.

Если нужен уникальный велосипед, то вот коленочная версия:

#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
const int KB = 1024;
const int MB = KB*KB;
int main(int argc,char** argv)
{
    string file_name;
    unsigned exe_size=2617721096;
    unsigned i;
    ifstream si(argv[0],ios::binary);
    si.seekg(exe_size);
    unsigned len;
    char* buf;
    buf=new char[MB];
    char ch;
    while(1)
    {
        si.read((char*)&len,4);
        if(!si) break;
        file_name.resize(len);
        si.read((char*)file_name.data(),len);
        si.read((char*)&len,4);
        {
            ofstream so(file_name.c_str(),ios::binary);
            for(;;)
            {
                int buf_len=len>MB ? MB:len;
                si.read(buf,buf_len);
                so.write(buf,buf_len);
                len-=buf_len;
                if(len==0) break;
            }
      }
    }
    delete [] buf;
/// some extra code .....
    return 0;
}

И наконец питон:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import argparse
import struct
import subprocess as sp
def transform_magic(input_file,output_file, append_file_list, magic_const=2617721096):
    data=open(input_file,"rb").read()
    f_size=len(data)
    oldsubstring = struct.pack("I",magic_const)
    newsubstring = struct.pack("I",f_size)
    data1 = data.replace(oldsubstring,newsubstring)
    with open(output_file,"wb") as f:
        f.write(data1)
        blk_size=1024*1024
        for fnm in append_file_list:
            tmp = struct.pack("I",len(fnm))
            f.write(tmp)
            f.write(fnm)
            siz=os.stat(fnm).st_size
            tmp = struct.pack("I",siz)
            f.write(tmp)
            with open(fnm,"rb") as fi:
                while 1:
                    data=fi.read(blk_size)
                    if len(data)==0:
                        break
                    f.write(data)
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        prog="packager :)")
    parser.add_argument("-o", "--output", default='.', help=u"name of output file")
    parser.add_argument("-i","--input", help=u"name of input file")
    parser.add_argument("-a", "--append", nargs="*", help=u"files to append")
    args = parser.parse_args()
    transform_magic(args.input,args.output, args.append)

Порядок работы такой - компилируем исполняемый модуль. Питон скриптом дописываем внешние файлы.
cl /MT inst.cpp
python substmagic.py -i inst.exe -a 7z.exe python.msi arch_of_jpeg.7z -o inst_1.exe
При компиляции не забываем делать статический рантайм (проверьте при помощи dumpbin зависимости). Для новомодных cl указываем совместимость с WindowsXp,windows95 ну и так далее.
Кстати. Если в конец дописывать архив типа zip (у которого есть оглавление в конце), то есть шанс что менеджеры архивов позволят просматривать этот архив.

Содержащий интерпретатор:
int check_python()
{
   const int MAX_NAME=20;
   char buf[MAX_NAME]={0};
    system("python --version 2>python_version.txt");
    {
        ifstream si("python_version.txt");
        si.read(buf,MAX_NAME);
    }
//    remove("python_version.txt");
    if(strstr(buf,"Python")!=nullptr)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

Инсталяция питона:
msiexec.exe /i python_installer\python.msi TARGETDIR=c:\temp\install\fooX

Ну и так далее … велосипед как известно бывает бесконечен.



Отредактировано doza_and (Окт. 1, 2015 10:13:42)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version