在使用 pyinstaller 制作的可执行文件中使用 pyunpack 并结合 try except [英] Use pyunpack inside an executable file made with pyinstaller in combination with try except

查看:157
本文介绍了在使用 pyinstaller 制作的可执行文件中使用 pyunpack 并结合 try except的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 pyunpack 有一个奇怪的行为,pyunpack 是一个在可执行文件中用于解包的包.

我想做以下事情:

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

首先我尝试以直接方式解压缩它,这会导致捕获到预期的错误.

在此错误捕获中,我首先添加 .7z 扩展名,然后解压缩将文件正确放入一个名为grog"的文件夹中,然后我将压缩文件取回原来的名称.

代码如下:

# test.pyfrom os.path import abspath, join, exists, dirname从操作系统导入重命名,mkdir从 Shutil 导入副本导入多处理导入pyunpackmultiprocessing.freeze_support()打印(0)name = "file_to_be_unzipped.sent"打印(一个")path = "C:\\Users\\myname\\eclipse-workspace-tms\\test_unzip_exe"打印(绝对路径(."))打印(b")unzip_dest = join(路径,grog")如果不存在(unzip_dest):mkdir(unzip_dest)打印(c")名称 = 加入(路径,名称)打印(d")打印(e")尝试:打印(1)pyunpack.Archive(name).extractall(unzip_dest)打印(2)除了 pyunpack.PatoolError 作为 ptr:打印(3)temp_f_name = 名称 + ".7z"打印(4)重命名(名称,temp_f_name)尝试:打印(5)pyunpack.Archive(temp_f_name).extractall(unzip_dest)打印(6)重命名(temp_f_name,名称)打印(7)除了 pyunpack.PatoolError 作为 pterr2:# 删除无用的 7z 扩展打印(8)重命名(temp_f_name,名称)打印(9)# 文件已经解压的情况if str(pterr2).find("不是存档"):打印(10)复制(名称,unzip_dest)打印(11)打印(12)除了 ValueError 作为 v:打印(13)打印(五)打印(14)

当我启动脚本 test.py 时,我得到了预期的行为:

<代码>0一种C:\Users\myname\eclipse-workspace-tms\test_unzip_exe乙Cd电子134567

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

pyinstaller --log-level=DEBUG test.spec

以及以下规范文件:

# -*- 模式:python ;编码:utf-8 -*-block_cipher = 无导入pyunpack进口帕托利布从 pyunpack 导入存档,PatoolError从 patolib.programs 导入 ar从 patolib.programs 导入弧从 patolib.programs 导入 archmage从 patolib.programs 导入 arj从 patolib.programs 导入 bsdcpio从 patolib.programs 导入 bsdtar从 patolib.programs 导入 bzip2从 patolib.programs 导入 cabextract从 patolib.programs 导入 chmlib从 patolib.programs 导入 clzip从 patolib.programs 导入压缩从 patolib.programs 导入 cpio从 patolib.programs 导入 dpkg从 patolib.programs 导入 flac从 patolib.programs 导入 genisoimage从 patolib.programs 导入 gzip从 patolib.programs 导入 isoinfo从 patolib.programs 导入 lbzip2从 patolib.programs 导入 lcab从 patolib.programs 导入 lha从 patolib.programs 导入拉萨从 patolib.programs 导入 lrzip从 patolib.programs 导入 lzip从 patolib.programs 导入 lzma从 patolib.programs 导入 lzop从 patolib.programs 导入 mac从 patolib.programs 导入 noarch从 patolib.programs 导入 p7azip从 patolib.programs 导入 p7rzip从 patolib.programs 导入 p7zip从 patolib.programs 导入 pbzip2从 patolib.programs 导入 pdlzip从 patolib.programs 导入 pigz从 patolib.programs 导入 plzip从 patolib.programs 导入 py_bz2从 patolib.programs 导入 py_echo从 patolib.programs 导入 py_gzip从 patolib.programs 导入 py_lzma从 patolib.programs 导入 py_tarfile从 patolib.programs 导入 py_zipfile从 patolib.programs 导入 rar从 patolib.programs 导入 rpm从 patolib.programs 导入 rpm2cpio从 patolib.programs 导入 rzip从 patolib.programs 导入 shar从 patolib.programs 导入缩短从 patolib.programs 导入星从 patolib.programs 导入 tar从 patolib.programs 导入 unace从 patolib.programs 导入 unadf从 patolib.programs 导入 unalz从 patolib.programs 导入解压缩从 patolib.programs 导入 unrar从 patolib.programs 导入 unshar从 patolib.programs 导入解压从 patolib.programs 导入 xdms从 patolib.programs 导入 xz从 patolib.programs 导入 zip从 patolib.programs 导入动物园从 patolib.programs 导入 zopfli从 patolib.programs 导入 zpaq# from pyunpack import Archive, PatoolErrora = Analysis(['test.py'],pathex=['C:\\Users\\myname\\eclipse-workspace-tms\\test_unzip_exe'],二进制文件=[],数据=[],hiddenimports=['pyunpack', 'patolib','patolib.programs.ar','patolib.programs.arc','patolib.programs.archmage','patolib.programs.arj','patolib.programs.bsdcpio','patolib.programs.bsdtar','patolib.programs.bzip2','patolib.programs.cabextract','patolib.programs.chmlib','patolib.programs.clzip','patolib.programs.compress','patolib.programs.cpio','patolib.programs.dpkg','patolib.programs.flac','patolib.programs.genisoimage','patolib.programs.gzip','patolib.programs.isoinfo','patolib.programs.lbzip2','patolib.programs.lcab','patolib.programs.lha','patolib.programs.lhasa','patolib.programs.lrzip','patolib.programs.lzip','patolib.programs.lzma','patolib.programs.lzop','patolib.programs.mac','patolib.programs.nomarch','patolib.programs.p7azip','patolib.programs.p7rzip','patolib.programs.p7zip','patolib.programs.pbzip2','patolib.programs.pdlzip','patolib.programs.pigz','patolib.programs.plzip','patolib.programs.py_bz2','patolib.programs.py_echo','patolib.programs.py_gzip','patolib.programs.py_lzma','patolib.programs.py_tarfile','patolib.programs.py_zipfile','patolib.programs.rar','patolib.programs.rpm','patolib.programs.rpm2cpio','patolib.programs.rzip','patolib.programs.shar','patolib.programs.shorten','patolib.programs.star','patolib.programs.tar','patolib.programs.unace','patolib.programs.unadf','patolib.programs.unalz','patolib.programs.uncompress','patolib.programs.unrar','patolib.programs.unshar','patolib.programs.unzip','patolib.programs.xdms','patolib.programs.xz','patolib.programs.zip','patolib.programs.zoo','patolib.programs.zopfli','patolib.programs.zpaq'],# hiddenimports=['Archive', 'PatoolError'],钩子路径=[],runtime_hooks=[],排除=[],win_no_prefer_redirects=假,win_private_assemblies=假,密码=块密码,noarchive=假)pyz = PYZ(a.pure, a.zipped_data,密码=block_cipher)exe = EXE(pyz,a. 脚本,[],exclude_binaries=真,名称='测试',调试=假,bootloader_ignore_signals=假,条=假,upx=真,控制台=真)科尔 = 收集(exe,a.二进制文件,a.zip 文件,a.数据,条=假,upx=真,upx_exclude=[],名称='测试')

然后在意外的很长时间后,我得到以下信息:

<代码>0一种C:\Users\myname\eclipse-workspace-tms\test_unzip_exe\dist\test乙Cd电子12

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

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

非常感谢

我取得了一些进展:在脚本中,在 print(1) 之后,如果我添加:

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

然后它再次工作.但是我有一个不可移植的 .exe

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

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

这将制作一个巨大的可执行文件,或者通过反复试验仅选择必要的文件,这需要很长时间.欢迎任何优雅的解决方案.

EDIT 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,'--非交互式','提炼',self.filename,'--outdir=' + 目录# '--详细']).call(timeout=self.timeout) `

问题是 sys.executable 设置为 test.exe 文件而不是 python.exe 可执行文件本身

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

最终用户希望在默认路径安装anaconda,然后pip install patoolpip install pyunpack,然后将exe文件复制到自己用户名的任意位置文件夹.

我这边:我在规范文件中添加 import pathlib, from pathlib import Path在规范文件的 hidden_​​mports 列表中,我添加:'pathlib', 'pathlib.Path',

然后在代码中,在print(1)之后,我添加:

abspath = abspath(".")user_path = Path(abspath).partsuser_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.

I have a strange behaviour for pyunpack, a package for unpacking, inside an executable.

I want to do the following thing:

I have a .7z type of file whose ending is not in .7z but in .sent.

First I try to unzip it the direct way, which leads to an expected error that is caught.

Inside this error catching, I am first adding the .7z extension, then I am unzipping the file properly into a folder called "grog", then I give the zipped file its original name back.

Here is the code below:

# 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)

When I launch the script test.py, I get the expected behaviour:

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

then I build the executable with the following command line:

pyinstaller --log-level=DEBUG test.spec

and the following spec 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')

and then after an unexpected long time, I get the following:

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

where the file in the destination ("grog") is not an unzipped file as wanted but simply a copy.

Does anybody have an idea of what is going wrong?

Thanks a lot

EDIT:

I have made some progress: In the script, after print(1), if I add:

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

Then it works again. However I have a non portable .exe

Since importing only the python.exe file via the spec file is not enough, the other solution would be to add into the spec file

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

which is going to make a huge executable, or pick one by one only the necessary files through trial and error, which takes ages. Any elegant solution is welcome.

EDIT 2: For more insight, the part from the pyunpack where the bug occurs is at the init file located in:

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

in the function extract_all_patool:

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

the problem being that sys.executable is set to the test.exe file instead of the python.exe executable itself

EDIT3: I found a semi-portable solution, not ideal but I found nothing better yet:

The end-user is expected to install anaconda in the default path, then pip install patool and pip install pyunpack, and then copy the exe file anywhere in his username folder.

On my side: I am adding in the spec file import pathlib, from pathlib import Path In the hidden_mports list of the spec file, I am adding: 'pathlib', 'pathlib.Path',

Then in the code, after print(1), I am adding:

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)

解决方案

The problem is, as you found in your 2nd edit, that pyunpack needs patool installed on the target system - which, in turn, requires python.

To fix this you need to:

  • Use tarballs or zipfiles; shutil supports theses.

  • Or require the end user to have python installed.

Another way of putting it is that to use pyunpack with pyinstaller, you need python on the target system.

这篇关于在使用 pyinstaller 制作的可执行文件中使用 pyunpack 并结合 try except的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆