python使用pyinstaller打包成的exe程序,代码修改重新打包就需要重新发送一次程序,略微麻烦,通过服务器存储新版本打包后的程序,检测和下载通过代码实现。
本文通过FTP局域网服务器的形式完成,使用serv-u软件配置FTP服务器,配置方式可移步下方站内链接
Serv-U配置FTP服务器
使用designer画一个简单的ui,如下图
转成py文件如下,命名为 update_test_ui.py代码如下
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'update_test.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainTestUp(object):
def setupUi(self, MainTestUp):
MainTestUp.setObjectName("MainTestUp")
MainTestUp.resize(603, 378)
self.centralwidget = QtWidgets.QWidget(MainTestUp)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(220, 150, 161, 61))
font = QtGui.QFont()
font.setPointSize(20)
font.setBold(True)
font.setWeight(75)
self.pushButton.setFont(font)
self.pushButton.setStyleSheet("background-color: rgb(0, 255, 255);")
self.pushButton.setObjectName("pushButton")
MainTestUp.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainTestUp)
self.menubar.setGeometry(QtCore.QRect(0, 0, 603, 23))
self.menubar.setObjectName("menubar")
MainTestUp.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainTestUp)
self.statusbar.setObjectName("statusbar")
MainTestUp.setStatusBar(self.statusbar)
self.retranslateUi(MainTestUp)
self.pushButton.clicked.connect(MainTestUp.close) # type: ignore
QtCore.QMetaObject.connectSlotsByName(MainTestUp)
def retranslateUi(self, MainTestUp):
_translate = QtCore.QCoreApplication.translate
MainTestUp.setWindowTitle(_translate("MainTestUp", "软件自升级测试"))
self.pushButton.setText(_translate("MainTestUp", "确定"))
定义一个main.py调用ui的py文件,并添加版本检测、FTP的服务器登录和文件下载功能,代码如下文章来源:https://www.toymoban.com/news/detail-626784.html
# -*- coding:utf-8 -*-
from PyQt5.Qt import *
import sys
import os
import socket
from ftplib import FTP
import update_test_ui
class UpdateTest(update_test_ui.Ui_MainTestUp, QMainWindow):
def __init__(self):
super(update_test_ui.Ui_MainTestUp, self).__init__()
super().__init__()
self.setupUi(self)
self.current_version = 'v2'
# 承接服务器的文件名称
self.remote_name = ''
# 承接远程服务器文件路径
self.remote_path = ''
# 当前exe程序地址
# self.local_folder = os.path.abspath(os.path.dirname(__file__))
# 运行第一步检查是否要更新
self.first_step()
def first_step(self):
try:
# 登录FTP
self.my_ftp = self.login_ftp("sq", "1")
print(self.my_ftp.welcome)
# 服务器文件目录
self.remote_path = self.getfile("/suite")
# 服务器文件名称
self.remote_name = self.remote_path.split("/")[-1]
# 服务器文件版本(设置服务器文件名称格式示例:软件名称_v1.exe)
remote_version = self.remote_name.split("_")[-1].split(".")[0]
# 判断服务器软件版本是否与本地版本一致
if self.current_version != remote_version:
# 本地路径,程序所在文件夹的上一级目录
local_path = os.path.abspath(os.path.join(os.getcwd(), "../."))
# 拼接一个本地路径的文件
local_file = local_path + "/" + self.remote_name
# 如果服务器文件还未下载
if not os.path.exists(local_file):
# 本地文件目录全地址
local_full = local_path + "/" + self.remote_name
# 执行下载
self.download_file(local_full, self.remote_path)
QMessageBox.warning(self, "提示", "最新版软件已下载,请在上一级目录安装使用")
# 服务器文件已下载
else:
# 本地已存在,请在上一级目录安装使用最新版软件
QMessageBox.warning(self, "提示", "请在上一级目录安装使用最新版软件")
# 设置下一步按钮不可操作,可强制使其使用新版本软件
self.pushButton.setEnabled(False)
else:
pass
except Exception:
pass
# 登录FTP服务器
def login_ftp(self, username, password):
try:
timeout = 60
socket.setdefaulttimeout(timeout)
ftp = FTP()
# 0主动模式 1 #被动模式
ftp.set_pasv(False)
host = "127.0.0.1"
port = 21
ftp.encoding = 'utf-8' # 'gbk'
ftp.connect(host, port)
ftp.login(username, password)
return ftp
except Exception:
pass
# 获得FTP目录及子目录下的文件名称
@staticmethod
def get_file_name(f):
names = f.split()
if len(names) < 9:
return ''
else:
file_names = names[8:]
res = ''
for name in file_names:
res = res + name + ''
return res.strip()
# 获得FTP目录及子目录下的文件
def getfile(self, path):
self.my_ftp.cwd(path)
file_list = []
self.my_ftp.retrlines("LIST", file_list.append)
for f in file_list:
if f.startswith("d"):
file_name = self.get_file_name(f)
if file_name == '.' or file_name == '..':
continue
path_a = self.my_ftp.pwd() + "/" + str(f).split(' ')[-1]
self.getfile(path_a)
self.my_ftp.cwd("..")
else:
if len(str(f).split(' ')) > 3:
# 得到文件名,并按照指定语句输出
a = self.my_ftp.pwd() + "/" + str(f).split(' ')[-1]
return a
# 判断本地是否已经存在相同文件
def is_same_size(self, local_file, remote_file):
try:
remote_file_size = self.my_ftp.size(remote_file)
except Exception:
remote_file_size = -1
try:
local_file_size = os.path.getsize(local_file)
except Exception:
local_file_size = -1
if remote_file_size == local_file_size:
return 1
else:
return 0
def download_file(self, local_file, remote_file):
if self.is_same_size(local_file, remote_file):
return
else:
try:
buf_size = 1024
file_handler = open(local_file, 'wb')
self.my_ftp.retrbinary('RETR %s' % remote_file, file_handler.write, buf_size)
file_handler.close()
except Exception:
return
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = UpdateTest()
ui.show()
sys.exit(app.exec())
代码还未完全实现自动化,站内有通过.bat进行自动化下载及安装的,对.bat文件的运行规则不懂,尝试未成功,文中的方法还需一步处理才能使用新版软件,且该方法让确定按钮不可点击,必须更新才可使用,若有大佬有更厉害的更加自动化的方法,请留下脚步。文章来源地址https://www.toymoban.com/news/detail-626784.html
到了这里,关于python程序打包成exe实现新版本的自动更新检测及下载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!