为EXE更新脚本添加下载进度条的技术问题求助
看起来你在PyUpdater的更新脚本里踩了几个常见的坑,我来帮你一步步梳理解决思路:
先揪出代码里的明显问题
错误的进度条更新逻辑
你的回调函数里写了bar.update(status.the_dwad),这明显是笔误——PyUpdater传给回调的是一个字典,不是对象,应该用status['downloaded']和status['total']来计算进度。stdout被完全屏蔽
你把sys.stdout重定向到了os.devnull,就算回调正常执行,进度条的输出也会被吞掉,这会让你误以为回调没触发。建议用日志级别控制来屏蔽无关输出,而不是直接关掉标准输出。模拟进度条和实际下载脱节
check_for_update里的bar = progressbar.ProgressBar()是一个模拟循环,和实际的下载进度完全无关,应该把进度条的初始化和更新逻辑放到回调函数里。Client初始化代码不完整
你最后一行的client = Client(...)缺少闭合的括号,这会直接导致代码报错。
修正后的完整代码示例
我基于你的需求重新写了可运行的代码,你可以参考:
import os import sys import time import logging from pyupdater.client import Client, ClientConfig import progressbar # 自定义Client配置,根据你的应用修改 class AppClientConfig(ClientConfig): APP_NAME = "YourAppName" UPDATE_URL = "你的更新服务器地址" # 必须配置这个才能拉取更新 # 全局进度条实例,在回调中复用 download_bar = None def download_progress_callback(status): global download_bar # 只处理下载中的状态 if status['status'] == 'downloading': total_bytes = status['total'] downloaded_bytes = status['downloaded'] percent_complete = int((downloaded_bytes / total_bytes) * 100) # 第一次收到下载状态时初始化进度条 if not download_bar: download_bar = progressbar.ProgressBar( max_value=100, widgets=[ 'Downloading: ', progressbar.Percentage(), ' ', progressbar.Bar(), ' ', progressbar.ETA() ] ) # 动态更新进度条 download_bar.update(percent_complete) # 可选:打印详细的下载信息 print(f"\r已下载: {downloaded_bytes}/{total_bytes} 字节", end='') # 下载完成时收尾 elif status['status'] == 'complete': if download_bar: download_bar.finish() print("\n✅ 更新包下载完成!") def check_and_download_update(): # 配置日志级别,屏蔽DEBUG级别的冗余输出,只保留警告及以上 logging.basicConfig(level=logging.WARNING) # 初始化Client,正确注册回调 config = AppClientConfig() try: client = Client( config, refresh=True, progress_hooks=[download_progress_callback], headers={'basic_auth': 'brofewfefwefewef:EKAXsWkdt5H6yJEmtexN'} ) except Exception as e: print(f"Client初始化失败: {str(e)}") return # 检查更新 update = client.check_for_update() if not update: print("当前已是最新版本") return # 开始下载更新 print(f"发现新版本,大小: {update.size} 字节,开始下载...") try: update.download() # 可选:下载完成后自动安装 # update.install() except Exception as e: print(f"下载失败: {str(e)}") if __name__ == "__main__": check_and_download_update()
额外的排查要点
确认PyUpdater版本兼容性
部分旧版本的PyUpdater可能不支持progress_hooks参数,如果上面的代码还是没触发回调,试试用client.register_progress_hook(download_progress_callback)来注册回调。清空缓存测试
如果PyUpdater已经缓存了更新包,下载过程会跳过,自然不会触发进度回调。你可以删除缓存目录(通常在~/.pyupdater/或应用的本地缓存文件夹)后再测试。验证回调参数结构
可以在回调函数开头加一行print(status),确认PyUpdater传给你的字典结构是否和预期一致,避免键名拼写错误。
内容的提问来源于stack exchange,提问作者user9155788

