У меня странное поведение для 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)