在pyinstaller与try-except组合生成的可执行文件中使用pyunpack



我在可执行文件中对pyunpack(一个用于解包的包(有一种奇怪的行为。

我想做以下事情:

我有一个.7z类型的文件,它的结尾不是.7z,而是.sent.

首先,我尝试以直接的方式解压缩它,这导致了一个预期的错误。

在这个错误捕获中,我首先添加了.7z扩展,然后解压缩将文件正确地放入一个名为"grog"的文件夹中,然后我将压缩后的文件的原始名称还给它。

下面是代码:

# 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:Usersmynameeclipse-workspace-tmstest_unzip_exe
b
c
d
e
1
3
4
5
6
7

然后我用以下命令行构建可执行文件:

pyinstaller --log-level=DEBUG test.spec

和以下规范文件:

# -*- 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:Usersmynameeclipse-workspace-tmstest_unzip_exedisttest
b
c
d
e
1
2

其中目标中的文件("grog"(不是所需的解压缩文件,而是一个副本。

有人知道出了什么问题吗?

非常感谢

编辑:

我已经取得了一些进展:在脚本中,打印(1(后,如果我添加:

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

然后它又起作用了。然而,我有一个不可移植的.exe

由于仅通过spec文件导入python.exe文件是不够的,另一种解决方案是将添加到规范文件中

("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可执行文件本身

第三版:我找到了一个半便携的解决方案,并不理想,但我还没有找到更好的解决方案:

最终用户应该在默认路径中安装anaconda,然后是pip install patoolpip install pyunpack,然后将exe文件复制到其username文件夹中的任何位置。

在我这边:我正在规范文件import pathlibfrom pathlib import Path中添加在spec文件的hidden_mports列表中,我添加了:'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)

问题是,正如您在第二次编辑中发现的那样,pyunpack需要在目标系统上安装patool,而目标系统又需要python。

要解决此问题,您需要:

  • 使用防水布或压缩文件;shutil支持论文。

  • 或者要求最终用户安装python。

另一种说法是,要将pyunpackpyinstaller一起使用,您需要在目标系统上使用python。

print(abspath("."))在python中直接运行时的输出为:

C:Usersmynameeclipse-workspace-tmstest_unzip_exe

使用pyinstaller运行时为:

C:Usersmynameeclipse-workspace-tmstest_unzip_exedisttest

因此,档案不会被提取到disttest文件夹中。

通过将path设置为返回abspath(".")的值,而不是将其硬编码为C:Usersmynameeclipse-workspace-tmstest_unzip_exe来解决此问题

最新更新