Используйте pyunpack внутри исполняемого файла, созданного с помощью pyinstaller, в сочетании с try, за исключением - PullRequest
5 голосов
/ 12 марта 2020

У меня странное поведение для pyunpack, пакета для распаковки, внутри исполняемого файла.

Я хочу сделать следующее:

У меня есть файл типа .7z, окончание которого не в .7z, а в .sent.

Сначала я пытаюсь распаковать его прямым способом, что приводит к ожидаемой ошибке, которая перехватывается.

Внутри этой перехвата ошибок я первый добавив расширение .7z, я распаковываю файл должным образом в папку с именем «grog», затем возвращаю zip-файлу его оригинальное имя.

Вот код ниже:

# test.py
from os.path import abspath, join, exists, dirname
from os import rename, mkdir
from shutil import copy
import multiprocessing
import pyunpack

multiprocessing.freeze_support()
print(0)
name = "file_to_be_unzipped.sent"
print("a")
path = "C:\\Users\\myname\\eclipse-workspace-tms\\test_unzip_exe"
print(abspath("."))
print("b")
unzip_dest = join(path, "grog")
if not exists(unzip_dest):
    mkdir(unzip_dest)
print("c")
name = join(path, name)
print("d")
print("e")
try:
    print(1)
    pyunpack.Archive(name).extractall(unzip_dest)
    print(2)
except pyunpack.PatoolError as pterr:
    print(3)
    temp_f_name = name + ".7z"
    print(4)
    rename(name, temp_f_name)
    try:
        print(5)
        pyunpack.Archive(temp_f_name).extractall(unzip_dest)
        print(6)
        rename(temp_f_name, name)
        print(7)
    except pyunpack.PatoolError as pterr2:
        # removing useless 7z extension
        print(8)
        rename(temp_f_name, name)
        print(9)
        # Case when the file is already unzipped
        if str(pterr2).find("Is not archive"):
            print(10)
            copy(name, unzip_dest)
            print(11)
        print(12)
except ValueError as v:
    print(13)
    print(v)
    print(14)

Когда я запускаю скрипт test.py, я получаю ожидаемое поведение:

0
a
C:\Users\myname\eclipse-workspace-tms\test_unzip_exe
b
c
d
e
1
3
4
5
6
7

, затем строю исполняемый файл с помощью следующей командной строки:

pyinstaller --log-level=DEBUG test.spec

и следующего spe c file:

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

import pyunpack
import patoolib
from pyunpack import Archive, PatoolError
from patoolib.programs import ar
from patoolib.programs import  arc
from patoolib.programs import  archmage
from patoolib.programs import  arj
from patoolib.programs import  bsdcpio
from patoolib.programs import  bsdtar
from patoolib.programs import  bzip2
from patoolib.programs import  cabextract
from patoolib.programs import  chmlib
from patoolib.programs import  clzip
from patoolib.programs import  compress
from patoolib.programs import  cpio
from patoolib.programs import  dpkg
from patoolib.programs import  flac
from patoolib.programs import  genisoimage
from patoolib.programs import  gzip
from patoolib.programs import  isoinfo
from patoolib.programs import  lbzip2
from patoolib.programs import  lcab
from patoolib.programs import  lha
from patoolib.programs import  lhasa
from patoolib.programs import  lrzip
from patoolib.programs import  lzip
from patoolib.programs import  lzma
from patoolib.programs import  lzop
from patoolib.programs import  mac
from patoolib.programs import  nomarch
from patoolib.programs import  p7azip
from patoolib.programs import  p7rzip
from patoolib.programs import  p7zip
from patoolib.programs import  pbzip2
from patoolib.programs import  pdlzip
from patoolib.programs import  pigz
from patoolib.programs import  plzip
from patoolib.programs import  py_bz2
from patoolib.programs import  py_echo
from patoolib.programs import  py_gzip
from patoolib.programs import  py_lzma
from patoolib.programs import  py_tarfile
from patoolib.programs import  py_zipfile
from patoolib.programs import  rar
from patoolib.programs import  rpm
from patoolib.programs import  rpm2cpio
from patoolib.programs import  rzip
from patoolib.programs import  shar
from patoolib.programs import  shorten
from patoolib.programs import  star
from patoolib.programs import  tar
from patoolib.programs import  unace
from patoolib.programs import  unadf
from patoolib.programs import  unalz
from patoolib.programs import  uncompress
from patoolib.programs import  unrar
from patoolib.programs import  unshar
from patoolib.programs import  unzip
from patoolib.programs import  xdms
from patoolib.programs import  xz
from patoolib.programs import  zip
from patoolib.programs import  zoo
from patoolib.programs import  zopfli
from patoolib.programs import  zpaq


# from pyunpack import Archive, PatoolError

a = Analysis(['test.py'],
             pathex=['C:\\Users\\myname\\eclipse-workspace-tms\\test_unzip_exe'],
             binaries=[],
             datas=[],
             hiddenimports=['pyunpack', 'patoolib',
                             'patoolib.programs.ar',
                             'patoolib.programs.arc',
                             'patoolib.programs.archmage',
                             'patoolib.programs.arj',
                             'patoolib.programs.bsdcpio',
                             'patoolib.programs.bsdtar',
                             'patoolib.programs.bzip2',
                             'patoolib.programs.cabextract',
                             'patoolib.programs.chmlib',
                             'patoolib.programs.clzip',
                             'patoolib.programs.compress',
                             'patoolib.programs.cpio',
                             'patoolib.programs.dpkg',
                             'patoolib.programs.flac',
                             'patoolib.programs.genisoimage',
                             'patoolib.programs.gzip',
                             'patoolib.programs.isoinfo',
                             'patoolib.programs.lbzip2',
                             'patoolib.programs.lcab',
                             'patoolib.programs.lha',
                             'patoolib.programs.lhasa',
                             'patoolib.programs.lrzip',
                             'patoolib.programs.lzip',
                             'patoolib.programs.lzma',
                             'patoolib.programs.lzop',
                             'patoolib.programs.mac',
                             'patoolib.programs.nomarch',
                             'patoolib.programs.p7azip',
                             'patoolib.programs.p7rzip',
                             'patoolib.programs.p7zip',
                             'patoolib.programs.pbzip2',
                             'patoolib.programs.pdlzip',
                             'patoolib.programs.pigz',
                             'patoolib.programs.plzip',
                             'patoolib.programs.py_bz2',
                             'patoolib.programs.py_echo',
                             'patoolib.programs.py_gzip',
                             'patoolib.programs.py_lzma',
                             'patoolib.programs.py_tarfile',
                             'patoolib.programs.py_zipfile',
                             'patoolib.programs.rar',
                             'patoolib.programs.rpm',
                             'patoolib.programs.rpm2cpio',
                             'patoolib.programs.rzip',
                             'patoolib.programs.shar',
                             'patoolib.programs.shorten',
                             'patoolib.programs.star',
                             'patoolib.programs.tar',
                             'patoolib.programs.unace',
                             'patoolib.programs.unadf',
                             'patoolib.programs.unalz',
                             'patoolib.programs.uncompress',
                             'patoolib.programs.unrar',
                             'patoolib.programs.unshar',
                             'patoolib.programs.unzip',
                             'patoolib.programs.xdms',
                             'patoolib.programs.xz',
                             'patoolib.programs.zip',
                             'patoolib.programs.zoo',
                             'patoolib.programs.zopfli',
                             'patoolib.programs.zpaq'],
             # hiddenimports=['Archive', 'PatoolError'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='test',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='test')

и затем после неожиданного долгого времени я получаю следующее:

0
a
C:\Users\myname\eclipse-workspace-tms\test_unzip_exe\dist\test
b
c
d
e
1
2

, где файл в месте назначения ("grog") не является разархивированный файл как хотел, но просто копия.

У кого-нибудь есть идея? что идет не так?

Большое спасибо

РЕДАКТИРОВАТЬ:

Я добился некоторого прогресса: В сценарии после print (1), если я добавлю:

sys.executable = "C:\\Users\\myname\\AppData\\Local\\Continuum\\anaconda3\\python.exe"

Затем снова работает. Однако у меня есть непереносимый файл .exe

. Так как недостаточно импортировать только файл python .exe через файл spe c, другим решением было бы добавить его в файл spe c

("C:\\Users\\myname\\AppData\\Local\\Continuum\\anaconda3\*,'.'")

, который собирается сделать огромный исполняемый файл или выбрать один за другим только необходимые файлы методом проб и ошибок, что занимает много времени. Любое элегантное решение приветствуется.

РЕДАКТИРОВАТЬ 2: Для получения дополнительной информации, часть из pyunpack, где возникает ошибка, находится в файле init , расположенном в:

"C:\\Users\\myname\\AppData\\Local\\Continuum\\anaconda3\\Lib\\site-packages\\pyunpack\\__init__.py"

в функции extract_all_patool:

   `p = EasyProcess([
        sys.executable,
        patool_path,
        '--non-interactive',
        'extract',
        self.filename,
        '--outdir=' + directory
        # '--verbose'
    ]).call(timeout=self.timeout) `

проблема в том, что для sys.executable задан файл test.exe вместо самого исполняемого файла python .exe

EDIT3: я нашел полупортативное решение, не идеальное, но пока не нашел ничего лучшего:

Ожидается, что конечный пользователь установит anaconda в путь по умолчанию, затем pip install patool и pip install pyunpack, а затем скопируйте exe-файл в любое место его папки с именем пользователя.

С моей стороны: я добавляю в файл spe c import pathlib, from pathlib import Path в список hidden_mports файла spe c , Я добавляю: 'pathlib', 'pathlib.Path',

Затем в коде, после print(1), я добавляю:

abspath = abspath(".")
user_path = Path(abspath).parts
user_path = join(user_path[0], user_path[1], user_path[2], user_path[3] )
conda_path = join("AppData", "Local", "Continuum", "anaconda3", "python.exe")
sys.executable = join(user_path, conda_path)

Ответы [ 2 ]

1 голос
/ 18 марта 2020

Проблема, как вы обнаружили во втором редактировании, заключается в том, что для pyunpack необходимо patool установить в целевой системе, что, в свою очередь, требует python.

Чтобы это исправить, вам необходимо:

  • Использовать тарболлы или zipfiles; shutil поддерживает тезисы.

  • Или требует, чтобы конечный пользователь установил python.

Другой способ выразить это используйте pyunpack с pyinstaller, вам нужно python в целевой системе.

0 голосов
/ 15 марта 2020

Выход print(abspath(".")) при непосредственном запуске в python:

C:\Users\myname\eclipse-workspace-tms\test_unzip_exe

При работе с pyinstaller:

C:\Users\myname\eclipse-workspace-tms\test_unzip_exe\dist\test

Таким образом, архив не извлекается в папка dist\test.

Исправьте это, установив path для возврата значения abspath(".") вместо жесткого кодирования C:\Users\myname\eclipse-workspace-tms\test_unzip_exe

...