1、代码文件 deploy.py
import os
from datetime import datetime
import shutil
import sys
import win32serviceutil
import win32service
import time
import tkinter as tk
import configparser
import logging
import ctypes
def createBackupFolderAndBackup(isFront,isBack):
now = datetime.now()
folderNameOfYmd = now.strftime("%Y%m%d")
folderNameOfHms = now.strftime("%H%M%S")
folderPathOfBackupNew = dirOfBackup + "\\" + folderNameOfYmd + "\\" + folderNameOfHms
os.makedirs(folderPathOfBackupNew, exist_ok=True)
logging.info("创建备份文件夹成功:"+ folderPathOfBackupNew)
if(isFront):
apkPathOfOld = os.path.join(deployDirOfApk , deployNameOfApk)
shutil.copy2(apkPathOfOld, folderPathOfBackupNew)
if not os.path.exists(os.path.join(folderPathOfBackupNew,deployNameOfApk)):
logging.error("apk备份失败")
sys.exit(1)
else:
logging.info("apk已完成备份")
if (isBack):
jarPathOfOld = os.path.join(deployDirOfJar , deployNameOfJar)
shutil.copy2(jarPathOfOld, folderPathOfBackupNew)
if not os.path.exists(os.path.join(folderPathOfBackupNew,deployNameOfJar)):
logging.error("jar备份失败")
sys.exit(1)
else:
logging.info("jar已完成备份")
def stopServiceAndDeployJar(service_name):
try:
win32serviceutil.StopService(service_name)
logging.info("停止服务")
except win32service.error as e:
if e.winerror == 1062:
pass
else:
raise
logging.info("等待服务完全停止")
while True:
try:
status = win32serviceutil.QueryServiceStatus(service_name)
if status[1] == win32service.SERVICE_STOPPED:
break
except win32service.error as e:
if e.winerror == 1060:
break
else:
raise
time.sleep(1)
logging.info("服务已完全停止")
pathOfJarOld = os.path.join(deployDirOfJar, deployNameOfJar)
try:
os.remove(pathOfJarOld)
logging.info(f"成功删除jar包:{pathOfJarOld}")
except OSError as e:
logging.error(f"删除jar包失败:{pathOfJarOld}")
raise
myPathOfJar = os.path.join(myDirOfJar, myNameOfJar)
shutil.copy2(myPathOfJar, deployDirOfJar)
if(not os.path.exists(os.path.join(deployDirOfJar, myNameOfJar))):
logging.error("拷贝新jar包失败")
sys.exit(1)
else:
os.rename(os.path.join(deployDirOfJar, myNameOfJar),os.path.join(deployDirOfJar, deployNameOfJar) )
logging.info("jar包替换成功")
try:
win32serviceutil.StartService(service_name)
logging.info("启动服务")
except win32service.error as e:
if e.winerror == 1056:
pass
else:
raise
def replaceApk():
pathOfApkOld = os.path.join(deployDirOfApk, deployNameOfApk)
try:
os.remove(pathOfApkOld)
logging.info(f"成功删除apk包:{pathOfApkOld}")
except OSError as e:
logging.error(f"删除apk包失败:{pathOfApkOld}")
raise
myPathOfApk = os.path.join(myDirOfApk, myNameOfApk)
shutil.copy2(myPathOfApk, deployDirOfApk)
if(not os.path.exists(os.path.join(deployDirOfApk, myNameOfApk))):
logging.error("拷贝新apk包失败")
sys.exit(1)
else:
os.rename(os.path.join(deployDirOfApk, myNameOfApk),os.path.join(deployDirOfApk, deployNameOfApk) )
logging.info("apk替换成功")
def deploy(isFront, isBack):
if(isFront and isBack):
logging.info("部署:前端+后端")
elif isFront:
logging.info("部署:前端")
elif isBack:
logging.info("部署:后端")
createBackupFolderAndBackup(isFront,isBack)
if(isBack):
stopServiceAndDeployJar(serviceName)
if(isFront):
replaceApk()
logging.info("done")
def configuration():
if not os.path.exists(configFilePath):
logging.error(f"配置文件{configFilePath}不存在")
sys.exit(1)
logging.info(f"开始解析配置文件{configFilePath}...")
global dirOfBackup,isFront,isBack
global deployDirOfJar,deployDirOfApk,deployNameOfJar,deployNameOfApk
global myDirOfJar,myDirOfApk,myNameOfJar,myNameOfApk
global serviceName,logFilePath
try:
config = configparser.ConfigParser()
config.read(configFilePath)
dirOfBackup = config.get("backup","dirOfBackup")
isFront = config.getboolean("deploy","isFront")
isBack = config.getboolean("deploy","isBack")
deployDirOfJar = config.get("deploy","deployDirOfJar")
deployDirOfApk = config.get("deploy","deployDirOfApk")
deployNameOfJar = config.get("deploy","deployNameOfJar")
deployNameOfApk = config.get("deploy","deployNameOfApk")
myDirOfJar = config.get("my","myDirOfJar")
myDirOfApk = config.get("my","myDirOfApk")
myNameOfJar = config.get("my","myNameOfJar")
myNameOfApk = config.get("my","myNameOfApk")
serviceName = config.get("service","serviceName")
logFilePath = config.get("log","logFilePath")
logging.info("配置文件解析成功")
except:
logging.error("配置文件解析失败")
sys.exit(1)
def initCheck():
logging.info("检查文件是否准备齐全")
if(isBack):
logging.info("检查后端文件和服务是否存在")
myJarPath = os.path.join(myDirOfJar,myNameOfJar)
if not os.path.exists(myJarPath):
logging.error(f"文件{myJarPath}不存在")
sys.exit(1)
oldJarPath = os.path.join(deployDirOfJar,deployNameOfJar)
if not os.path.exists(oldJarPath):
logging.error(f"文件{oldJarPath}不存在")
sys.exit(1)
try:
status = win32serviceutil.QueryServiceStatus(serviceName)
except win32service.error as e:
if e.winerror == 1060:
logging.error(f"服务{serviceName}不存在")
sys.exit(1)
if(isFront):
logging.info("检查前端文件是否存在")
myApkPath = os.path.join(myDirOfApk,myNameOfApk)
if not os.path.exists(myApkPath):
logging.error(f"文件{myApkPath}不存在")
sys.exit(1)
oldApkPath = os.path.join(deployDirOfApk,deployNameOfApk)
if not os.path.exists(oldApkPath):
logging.error(f"文件{oldApkPath}不存在")
sys.exit(1)
def isAdmin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
configFilePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(sys.executable))),"config.ini")
dirOfBackup = "E:\\test\\backup"
deployDirOfJar = "E:\\apiTest"
deployDirOfApk = "E:\\test\\targetApp"
myDirOfJar = "E:\\test\\deployed"
myDirOfApk = "E:\\test\\deployed"
deployNameOfJar = "testapp.jar"
deployNameOfApk = "zfapp.apk"
myNameOfJar = "zbj-fwapp-api-dev.jar"
myNameOfApk = "zfapp.apk"
serviceName = "testapp"
logFilePath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(sys.executable))),"logs\\log.txt")
isFront = False
isBack = False
logging.basicConfig(filename=logFilePath,
format='%(asctime)s %(levelname)s : %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filemode='a',
level=logging.INFO
)
if isAdmin():
logging.info("当前程序以管理员身份运行,继续")
configuration()
if(isFront or isBack):
initCheck()
deploy(isFront,isBack)
else:
logging.info("不进行部署,结束")
else:
logging.error("当前程序不是以管理员身份运行,结束")
2、配置文件 config.ini
[backup]
dirOfBackup = E:\\test\\backup
[deploy]
isFront = False
isBack = False
deployDirOfJar = E:\\apiTest
deployDirOfApk = E:\\test\\targetApp
deployNameOfJar = testapp.jar
deployNameOfApk = zfapp.apk
[my]
myDirOfJar = E:\\test\\deployed
myDirOfApk = E:\\test\\deployed
myNameOfJar = zbj-fwapp-api-dev.jar
myNameOfApk = zfapp.apk
[service]
serviceName = testapp
[log]
logFilePath = E:\\test\\deployed\\logs\\log.txt
3、使用pyinstaller打包成exe
4、readme.txt
1、使用配置文件config.ini进行配置:
dirOfBackup ——备份文件夹路径
isFront/isBack ——设置为True/False来控制部署前端还是后端
deployDirOfJar ——后端部署的文件夹路径
deployDirOfApk ——前端部署的文件夹路径
deployNameOfJar ——后端部署的Jar包名称
deployNameOfApk ——前端部署的apk名称
myDirOfJar —— 我的Jar包存放文件夹路径
myDirOfApk ——我的Apk包存放文件夹路径
myNameOfJar ——我的Jar包名称
myNameOfApk ——我的Apk包名称
serviceName ——服务的名称
logFilePath ——日志文件存放的路径
2、使用管理员身份运行dist/deploy.exe(或通过windows计划任务定时运行)
3、查看log日志查看运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律