简介
windows 自动更新程序
最近用python给开发了一个windows监控软件,用于监控电脑的运行情况,更新电脑软件。由于有几十电脑,一台一台手动更新就不太靠谱了,于是就开发了一个自动更新软件的的程序。
1.基本思路
基本步骤如下
1.获取远程配置文件
2.对比本地配置文件
3.获取更新文件
4.进行更新
2.代码实现
使用到的库
os 用于执行和停止程序
urllib.request 用于获取运程文件
base64 用于解析数据
datetime 用于格式化时间
time 用于休眠程序
json 用于解析json
2.1核心代码如下
def run():
# 循环获取
while True:
try:
# 1.加载远程配置
online_json = json.loads(get_data_by_url("http://xxx/HboUpdateVersion.json"))
# 1.1加载本地配置
local_json = read_version_json()
# 2.比较远程配置和本地配置
for program_name in online_json:
if local_json.get(program_name):
# 2.1版本号有更新
if online_json.get(program_name).get("version") > local_json.get(program_name).get("version"):
# 3.获取文件 4.更新exe文件
create_exe_file(online_json.get(program_name).get("url"), program_name)
# 5.判断是否需要启动运行
if online_json.get(program_name).get("is_run"):
run_exe(program_name)
else:
create_exe_file(online_json.get(program_name).get("url"), program_name)
if online_json.get(program_name).get("is_run"):
run_exe(program_name)
# 更新version
write_version_json(data=online_json)
except Exception:
write_log("更新失败")
# sleep 1 hour
time.sleep(3600)
if __name__ == '__main__':
run()
2.2配置文件格式
配置文件放在文件服务上,程序读取后和本地配置进行比较更新。
这里可以使用配置中心,或者自己实现个配置服务接口代替
{
"HboMonitor": -- 应用名称
{
"version": 1, -- 版本号
"url": "http://xxx/HboMonitor", -- 远程待更新文件地址
"is_run":true -- 是否需要立即运行
},
"HboHello":
{
"version": 2,
"url": "http://xx/HboHello",
"is_run":false
}
}
3.完整代码
# -*- coding: utf-8 -*-
# @file : HboUpdate.py
# @author : songxulin
# @date : 2021:08:20 14:00:00
# @version: 1.0
# @desc : 自动更新exe
import os
import urllib.request
import base64
import datetime
import time
import json
# 公共目录
directory = "C:/xxx"
def create_exe_file(url, file_name):
"""创建文件"""
try:
if not os.path.exists(directory):
os.mkdir(directory)
# 更新替换文件前需停止待更新程序
os.system('taskkill /f /t /im %s.exe' % file_name)
if not url:
return "url is null"
b64_text = get_data_by_url(url)
exe_file_path = "%s/%s.exe" % (directory, file_name)
f = open(exe_file_path, 'wb+')
f.write(base64.b64decode(b64_text))
f.close()
except IOError:
return "cannot open url"
except Exception as e:
return "fail"
return "success"
def run_exe(file_name):
"""启动程序"""
os.system('start "" "%s/%s.exe"' % (directory, file_name))
def get_data_by_url(url):
"""获取远程数据"""
header = {
'User-Agent': 'Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
} # 头部信息
request = urllib.request.Request(url=url, headers=header) # 请求处理
b64_text = urllib.request.urlopen(request).read() # 读取结果
return b64_text
def read_version_json():
"""读取本地版本文件"""
if not os.path.exists("%s/version.json" % directory):
return {}
with open("%s/version.json" % directory, mode='r', encoding='utf-8') as j:
return json.load(j)
def write_version_json(data):
"""更新写入版本文件"""
with open('%s/version.json' % directory, 'w') as f:
json.dump(data, f)
def write_log(text):
"""记录日志"""
f = open('%s/HboUpdate.log' % directory, mode='a', encoding='utf-8')
f.write(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S' + "\t" + text + "\n"))
f.close()
def run():
while True:
try:
online_json = json.loads(
get_data_by_url("http://xxx/HboUpdateVersion.json"))
local_json = read_version_json()
if online_json == local_json:
# sleep 1 hour
time.sleep(3600)
continue
for program_name in online_json:
if local_json.get(program_name):
if online_json.get(program_name).get("version") > local_json.get(program_name).get("version"):
write_log("更新:%s 版本:%s->%s" % (
program_name, local_json.get(program_name).get("version"),
online_json.get(program_name).get("version")))
write_log("更新地址:%s" % online_json.get(program_name).get("url"))
write_log("更新结果:%s" % create_exe_file(online_json.get(program_name).get("url"), program_name))
if online_json.get(program_name).get("is_run"):
run_exe(program_name)
else:
write_log(
"更新:%s 版本: %s" % (program_name, online_json.get(program_name).get("version")))
write_log("更新地址:%s" % online_json.get(program_name).get("url"))
write_log("更新结果:%s" % create_exe_file(online_json.get(program_name).get("url"), program_name))
if online_json.get(program_name).get("is_run"):
run_exe(program_name)
# 更新version
write_version_json(data=online_json)
except Exception:
write_log("更新失败")
# sleep 1 hour
time.sleep(3600)
if __name__ == '__main__':
run()
程序可以使用pyinstaller打包成 exe直接在windows下运行,将程序设置为自启动。