cx\u冻结:LookupError:未知编码:cp437

2024-09-26 17:41:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用cx\u Freeze来创建我的软件的exe,我需要实现一个自动更新程序。所以到目前为止我所做的是检查是否有软件的更新版本,是否有程序应该下载一个zip文件,其中包含更新。到现在为止,一直都还不错。但是,如果要通过解压zip文件来安装更新,我会遇到一个LookupError:

  File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "Rocketupload.py", line 1947, in download
  File "C:\Program Files (x86)\Python37-32\lib\zipfile.py", line 1222, in __init__
    self._RealGetContents()
  File "C:\Program Files (x86)\Python37-32\lib\zipfile.py", line 1327, in _RealGetContents
    filename = filename.decode('cp437')
LookupError: unknown encoding: cp437

Rocketupload第1947行:

z = zipfile.ZipFile(file_name, allowZip64=True)

奇怪的是,当我用shell运行软件时,没有cx\u Freeze创建的exe,我没有同样的问题。所以我认为这个问题与exe的创建有关。你知道吗

我还将提供用于下载和解压缩更新版本zip的代码:

def download(self):
    exePath = sys.argv[0]
    self.downloadBtn.configure(state="disabled")
    file_name = SettingsManager.find_data_file("RocketUpload_v" + str(self.versionNumber) + ".zip")
    with open(file_name, "wb") as f:
        response = requests.get(self.downloadFile, stream=True)
        print(response)
        total_length = response.headers.get('content-length')

        dl = 0
        total_length = int(total_length)
        for data in response.iter_content(chunk_size=4096):
            downloadedSize = str(round(int(dl) / self.MBFACTOR, 2))
            if (downloadedSize[-3]) != ".":
                downloadedSize += "0"

            self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + " Downloading: [" + downloadedSize + "MB/" + str(round(int(self.maximum) / self.MBFACTOR, 2)) + "MB]")
            dl += len(data)
            self.num.set(dl)
            self.parent.update()
            f.write(data)
        self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + " Finished: [" + str(round(int(self.maximum) / self.MBFACTOR, 2)) + "MB/" + str(round(int(self.maximum) / self.MBFACTOR, 2)) + "MB]")
        time.sleep(1)
        self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + ": Installing...")
        f.close()

    excluded = set(["rsc"])
    for root, dirs, files in os.walk(SettingsManager.find_data_file("."), topdown=True):
        dirs[:] = [d for d in dirs if d not in excluded]
        for filename in files:
            file_path = os.path.join(root,filename)
            if file_path[-4:] != ".zip":
                os.rename(file_path, file_path + ".tmp")

    time.sleep(2)

    z = zipfile.ZipFile(file_name, allowZip64=True) #<---- That is where the error happens
    uncompress_size = sum((file.file_size for file in z.infolist()))
    print(uncompress_size)
    self.progress.configure(maximum=uncompress_size)
    self.num.set(0)
    extracted_size = 0

    for file in z.infolist():
        self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + " Installing: [" + str(int(extracted_size/uncompress_size*100)) + "%/100%]")
        extracted_size += file.file_size
        self.num.set(extracted_size)
        self.parent.update()
        z.extract(file)

    self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + " Installing: [100%/100%]")
    self.parent.update()
    time.sleep(0.5)

    self.progressVar.set("RocketUpload_v" + str(self.versionNumber) + " Installing: Finished. Relaunch App Now.")
    self.parent.update()
    self.finished = True
    f.close()

我要做的是将所有与正在运行的软件相关的文件重命名为临时文件,然后解压zip文件,因为它不允许覆盖打开的文件。你知道吗

这是我的setup.py用cx\u freeze冻结我的软件:

import sys
import setuptools
from cx_Freeze import setup, Executable

# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(  name = "RocketUpload",
        version = "1.0",
        options = {
            "build_exe": {
                "packages": ["os","time","csv","sys","shutil","re","random","pickle","traceback", "autoit", "ctypes", "threading", "_thread", "configparser", "platform", "subprocess", "queue", "multiprocessing", "psutil", "datetime", "webbrowser","PIL","tkinter","cryptography","abc","selenium", "bs4", "requests", "zipfile"],
                'includes': ['Rocketupload','paywhirl'],
                'include_msvcr': True,
            },
        },
        executables = [Executable("Rocketupload.py", base=base,icon = "rsc/imgs/LogoBlackIcon.ico")]
        )

我的预期结果是能够解压我下载的zip文件。你知道吗


Tags: 文件inpyselftrueforsizezip
1条回答
网友
1楼 · 发布于 2024-09-26 17:41:16

尝试将"encodings"添加到packages脚本中的setup.py列表:

"packages": ["encodings", "os","time","csv","sys","shutil","re","random","pickle","traceback", "autoit", "ctypes", "threading", "_thread", "configparser", "platform", "subprocess", "queue", "multiprocessing", "psutil", "datetime", "webbrowser","PIL","tkinter","cryptography","abc","selenium", "bs4", "requests", "zipfile"],

引用cx\u Freeze的主要开发者在quite old issue中的回答:

You need to add the option " include-modules encodings.cp437" on your command line as this module is loaded dynamically at runtime (so static analysis cannot catch that).

如果您没有使用最新的cx\u Freeze版本(6.0),那么将cx\u Freeze更新到此版本可能就足以解决此问题。你知道吗

相关问题 更多 >

    热门问题