软件更新服务之客户端更新

在现在的软件开发和使用中,软件的更新是很关键的一环。通过不停的更新软件,迭代,给用户带来更好的体验和更多的功能以及修复用户反馈的bug。我们在更新的软件的时候,如果每次都要用户从新安装软件的话,想必体验也不会很好,也很麻烦,浪费不必要的资源。
那么今天就继续给大家说要一下软件更新服务里面的客户度端更新。有些后面关注的同学没看到前面写的那篇服务端搭建的文章的话,可以待会出门左拐看一下。

豪华分割线


在这次客户端编写过程当中,为了给大家可以看到更加直观的效果就简单做了个界面,使用到了以下技术:

PyQt5
Python3
python序列化
urllib下载文件

大家先在pycharm中,把pyqt5给装上,pip install PyQt5,也可以在设置的里面的project interpreter 里面下载安装。
接着,就配置好外部工具,QtDesigner以及PyUIC这两个外部工具。
由于这两个工具的配置比较简单,我就不作说明了,大家可以自行百度一下,随意参考一种都可以顺利配置好这两个外部工具的。
接着,打开designer来对界面进行绘制设计。

大概就这样就可以了,一个标题、一个文本框、两个按钮就足够显示了。
虽然长得丑了一点,但是我们这次文章的关键不是界面的美化,所以就不作其他处理了。
保存好,再到pycharm里面对ui文件运行一下PYUIC就OK

这个时候,界面代码已经由设计图转成Python代码了,可以看到它生成了一个类,但是还跑不动,因为没有引用到它。所以,我们先放它到一边。

接着,我们就重新创建好一个py文件,导入我们预期就要用到的库。

hashlib 计算MD5用
sys
pickle 计算序列化
urllib 下载文件
urllib3
os 处理文件 和目录

这几个库导进来后,就开始新建一个类,继承刚才生成的那个界面类。写法如下

python    11行

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MainWindow, self).__init__(parent)self.setupUi(self)if __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)mainWindow = MainWindow()mainWindow.show()sys.exit(app.exec_())

这个时候,运行文件就可以显示出界面了。而且这样将界面和实际操作的代码分隔开来可以避免重新UIC界面时,代码会丢失,而导致要重写的问题。

OK,界面出来后,就要实现功能了。更新,更新怎么做?
上一篇更新服务文章已经提供了更新说明和下载服务了,所以,我们这次就利用好这些接口。
我们又新建一个类,专门用来处理更新文件的,所以就简单的叫UpdateFiles吧。

在这里再过一次流程:

从服务器上面拿到清单文件
反序列清单文件
比较里面的数据,如果文件存在则计算MD5,相同就跳过,不相同就准备下载
如果文件不存在,则不用计算MD5了,直接准备下载

所以,就需要3个函数,下载文件函数、计算MD5值函数、检查更新函数
按照这三个需求以及上一篇的接口,我们可以很快就完成代码的编写。
在UpdateFiles这个类中完成这几个功能的开发后,便可以很方便的完成更新文件的服务功能。
由于已经整理成一个类,所以,后面如果各位希望可以在自己代码中用到这样子的更新服务的话吗,就可以直接将这个类copy过去,改一些东西就可以用了。

这里说一下写代码踩的坑吧
1、因为用的是urllib去下载的文件,多级目录下,文件不存在的时候,并不会在目标目录自动新建目录。所以,在下载的时候,需要对路径进行处理,筛选出目标目录,mkdir创建一下目录后,再下载目标文件。具体实现可以看downloadFiles函数,代码很简单,理解起来肯定没问题。

效果如下

点击检查更新会将需要更新的文件列在上面
点击下载便会自动下载文件了。而且有个简单的进度条可以看到进度。

代码我就直接贴出来了。

python    107行

# -*- coding: utf-8 -*-
# @Time    : 4/1/2019 19:36
# @Author  : MARX·CBR
# @File    : updateClient.py
import json
import hashlib
import sys
import pickle
from PyQt5 import QtWidgets
from urllib3 import request
from urllib import request
import osfrom updateServer.UClient.sample import Ui_MainWindowclass MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MainWindow, self).__init__(parent)self.setupUi(self)self.pushButton.clicked.connect(self.showUpdate)self.pushButton_2.clicked.connect(self.updateNow)self.updateList = []self.updateServer = UpdateFiles()def showUpdate(self):self.textBrowser.clear()self.updateList = self.updateServer.check_update()for j in self.updateList:print(j)self.textBrowser.append(j)def updateNow(self):all_file_number = 0for j in self.updateList:self.updateServer.downloadFiles(j)all_file_number += 1vau = int((all_file_number * 100) / len(self.updateList))self.progressBar.setValue(vau)self.repaint()class UpdateFiles():def __init__(self):self.server = '47.101.195.58'self.port = '1213'self.directory = os.getcwd()def downloadFiles(self, key):checkurl = 'http://' + self.server + ':' + self.portfile_dir = self.directory + '\\' + keyfile_dir = file_dir.replace('/', '\\')if os.path.exists(file_dir):os.remove(file_dir)request.urlretrieve(checkurl + '/' + key, file_dir)else:newpath = '\\'.join(file_dir.split('\\')[:-1:])print(newpath)try:os.mkdir(newpath)request.urlretrieve(checkurl + '/' + key, file_dir)except:request.urlretrieve(checkurl + '/' + key, file_dir)def Getfile_md5(self, filename):if not os.path.isfile(filename):returnmyHash = hashlib.md5()f = open(filename, 'rb')while True:b = f.read(8096)if not b:breakmyHash.update(b)f.close()return myHash.hexdigest()def check_update(self):data = {}updateList = []checkurl = 'http://' + self.server + ':' + self.portrequest.urlretrieve(checkurl + '/.listFile', ".listFile")with open(".listFile", "rb") as f:data = pickle.load(f)print(data)for key in data:new_md5 = data[key]file_dir = self.directory + '\\' + keyif os.path.exists(file_dir):oldmd5 = self.Getfile_md5(file_dir)if oldmd5 != new_md5:print(new_md5, "准备下载")updateList.append(key)# print(new_md5)else:updateList.append(key)print('准备下载', file_dir)return updateListif __name__ == "__main__":app = QtWidgets.QApplication(sys.argv)mainWindow = MainWindow()mainWindow.show()sys.exit(app.exec_())

好了,本次文章就到这里了,这篇是综合上一篇服务端搭建写的。
打算将这个软件更新服务写几篇内容出来分享给大家的

这里是第二篇,给大家介绍软件更新服务中,客户端该怎么处理。
第三篇打算给大家讲一下热更新,如何实现无须重启便完成软件的更新。
之前那篇服务端搭建的代码存在一些bug,我已经更新了。然后连同本次代码,将整个服务端以及客户端一起提交到GitHub中了。

欢迎大家到GitHub中fork使用,如果能给个star就 最好啦。

GitHub地址:https://github.com/97CBR/SoftwareUpdateServer

推荐阅读:
软件更新服务之服务端搭建
是谁让我的线上测试服务器突然变成游戏私服
安卓简单逆向修改
搜索引擎的那些小技巧

本文对你有没帮助呀,喜欢的话,记得留言、点赞、转发呀。谢谢各位!

二维码为被扫而生

软件更新服务之客户端更新相关推荐

  1. win10组件服务计算机是红色的,KB4023057:Windows 10更新服务组件的更新

    摘要 此更新包括对 Windows 10 中的 Windows 更新服务组件(版本 1507.1511.1607.1703.1709.1803.1909.2004.20H2 和 21H1)的可靠性改进 ...

  2. Output Messenger 2.0.10 Full - 即时消息软件(服务端+客户端)

    请访问原文链接:https://sysin.org/blog/output-messenger-2-update/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页: ...

  3. Windows WSUS更新服务

    WSUS更新服务 题目 一.安装更新服务 二.创建更新组 三.配置策略并更新 四.客户端测试 提示:有任何问题私聊我 题目 WSUS更新服务 安装WSUS更新服务,更新补丁目录设置为"c: ...

  4. Jenkins构建(14):Jenkin实现自动化更新服务(一)

    Jenkin实现自动化更新服务(调用远程服务器自动化更新)V0.11版本之前 一.Jenkin实现自动化更新服务的思路: 公司的产品经常要更新服务,手动更新服务太繁琐,可以通过Jenkins实现自动化 ...

  5. 客户机服务器文件更新,服务端数据更新,如何更新客户端缓存

    我是服务端 被客户端吐槽说我的API接口没有数据版本号(用来表示后台数据是否有更新),导致客户端缓存不知道什么时候更新,每次都要请求服务端数据 对此有几点疑虑,特来请教各位大拿 客户端缓存更新是否真的 ...

  6. 服务器win系统更新如何设置,Windows服务器更新服务的配置

    0x01 WSUS客户端 wsus客户端可以使windows的各种系统(windows7\8\10\server). 无须安装任何软件. 0x02 客户端配置 wsus客户端通过配置本地组策略来实现. ...

  7. 软件自动升级系统:支持exe程序覆盖更新、目录结构、更新更新程序自身、更新sql、执行bat批处理...

    软件自动升级系统说明 目录 一.         自动升级需要需要实现些什么?... 1 二.         服务器安装... 2 三.         客户端配置... 4 四.         ...

  8. 【CS】客户端更新(一)——更新程序文件方式

    一.前言 最近接手了个半CS半BS的项目.怎么说呢?由于项目比较紧张,而且BS的项目已经做出来了,虽说不是很好,但是也可以满足增删改查的操作.但是CS的项目比较紧,给了一个月的时间,如果每个功能都做的 ...

  9. 乐变黄杲:当前如何选择App热更新服务

    在2017年6月这个时间点,我们有必要谈谈热更新这个技术到底何去何从. \\ 上半年苹果的两次警告,通知iOS开发者在6月12日前移除热更新相关代码,否则将会下架相关App,一时间风声鹤唳,那么App ...

最新文章

  1. php判断网页编码,python判断网页编码的方法
  2. C++ main函数中参数argc和argv
  3. php与mysql字符集,php与mysql字符集编码问题
  4. fail safe java_Java中快速失败(fail-fast)和安全失败(fail-safe)的区别?
  5. Oracle编程入门经典 第1章 了解Oracle
  6. 折线插值_使用地形转栅格插值工具创建水文高程表面
  7. 哪个小姐姐是假的?Yann LeCun说合成人脸并不难分辨
  8. c语言uppercase恢复小写,C语言转换字符串为大写和小写
  9. “为了拿下 Offer,我在技术面试时迎合面试官,给了错误答案!”
  10. php中strtotime函数,PHP中strtotime函数用法举例
  11. SQL Express数据库的连接问题
  12. 在salesforce中实现鼠标悬停显示提示框效果,并对显示框内容进行微缩页面布局
  13. 2021美国大学生数学建模竞赛C题翻译版
  14. 苹果xr如何关机_苹果新系统让这些 iPhone 电量满血复活
  15. 车载网络: CAN (Control Area Network) 控制器局域网络
  16. activiti查询我的待办任务以及审批
  17. 加解密篇 - 什么是加密加盐 (分析web3j的加盐处理)
  18. 爬虫项目实战二:爬取起点小说网
  19. 7-29 二分法求多项式单根 (20 分)
  20. PowerDesigner(CDM)画ER图并导出且在DBMS中运行

热门文章

  1. 整型,长整型,无符号整型等 大端和小端(Big endian and Little endian)
  2. 数据库系统原理 - - (7、8)数据库应用设计与开发实例 + 数据管理技术的发展
  3. php字体加粗,php imagettftext 水印 粗体
  4. python deepcopy 丢失_Python muliple deepcopy行为
  5. 华中科技大学校长李培根演讲稿(转载)
  6. 小程序数据可视化图表绘制wxcharts
  7. OpenCV图像处理学习十三,图像金字塔——高斯金字塔和拉普拉斯金字塔
  8. 【C++】高斯金字塔和拉普拉斯金字塔原理和实现
  9. opencv--图像金字塔--高斯金字塔
  10. https://docs.icons8.com/ 切片 钢笔 布尔计算