cx_Freeze: LookupError: неизвестная кодировка: cp437 - PullRequest
1 голос
/ 21 сентября 2019

Я использую cx_Freeze, чтобы создать исполняемый файл моего программного обеспечения, и мне нужно реализовать автообновление.Итак, что я пока делаю, так это проверяю, есть ли обновленная версия программного обеспечения и должна ли она загружать 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

Строка 1947 из Rocketupload:

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

Странно, у меня нет того жепроблема, когда я запускаю программу оболочкой, без exe-файла, созданного cx_Freeze.Поэтому я считаю, что проблема заключается в создании exe.

Я также предоставлю код, который я использую для загрузки и распаковки файла updated-version-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_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-файл.

1 Ответ

0 голосов
/ 23 сентября 2019

Попробуйте добавить "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_Freeze в довольно старой проблеме :

Вам необходимо добавить опцию «--include-modules encodings.cp437» в командной строке, так как этот модуль загружается динамически во время выполнения (поэтому статический анализ не может это перехватить).

Если вы не используете последнюю версию cx_Freeze (6.0), возможно, обновления cx_Freeze до этой версии может быть достаточно для решения проблемы.

...