[patch] 新增自动更新功能 模块 优化进度条显示 横幅图片资源上传

This commit is contained in:
2025-10-29 14:58:09 +08:00
parent 8f1b51ef4f
commit 8c0580d140
5 changed files with 545 additions and 199 deletions

View File

@@ -14,6 +14,7 @@ import time
import socket
from pathlib import Path
from PyQt5.QtCore import QThread, pyqtSignal
import ctypes
class UpdateDownloader(QThread):
@@ -131,6 +132,59 @@ class UpdateDownloader(QThread):
self.is_cancelled = True
def run_as_admin(script_path):
"""
以管理员身份运行脚本Windows UAC提升
特点:
- 在GUI退出前弹出UAC提示
- 用户点击"允许"后,脚本以管理员身份运行
- 用户点击"取消"返回False
Args:
script_path: 批处理脚本路径
Returns:
bool: True表示成功启动用户点击允许False表示失败或用户取消
"""
try:
print(f"[RunAsAdmin] 请求管理员权限执行: {script_path}")
# 使用 ShellExecute 以管理员身份运行
# "runas" 参数会触发UAC提示
ret = ctypes.windll.shell32.ShellExecuteW(
None, # hwnd: 父窗口句柄None表示无父窗口
"runas", # lpOperation: 以管理员身份运行
"cmd.exe", # lpFile: 要执行的程序
f'/c "{script_path}"', # lpParameters: 命令行参数
None, # lpDirectory: 工作目录None表示当前目录
0 # nShowCmd: 0=隐藏窗口
)
# 返回值说明:
# >32: 成功
# <=32: 失败(具体错误码)
# - 5: 用户拒绝UAC点击"否"
# - 2: 文件未找到
# - 其他: 其他错误
if ret > 32:
print(f"[RunAsAdmin] ✅ 成功:用户已授权,脚本正在以管理员身份运行")
return True
elif ret == 5:
print(f"[RunAsAdmin] ⚠️ 用户取消了UAC授权返回码: {ret}")
return False
else:
print(f"[RunAsAdmin] ❌ 启动失败(返回码: {ret}")
return False
except Exception as e:
print(f"[RunAsAdmin] ❌ 异常: {e}")
import traceback
traceback.print_exc()
return False
def install_update_and_restart(installer_path):
"""
简化版更新安装文件替换方式不使用NSIS安装
@@ -138,9 +192,10 @@ def install_update_and_restart(installer_path):
工作流程:
1. 将安装包移动到程序目录
2. 创建替换脚本
3. 脚本等待程序退出
4. 脚本解压并替换文件
5. 重启程序
3. 以管理员身份启动脚本提前弹出UAC
4. 脚本等待程序退出
5. 脚本执行静默安装
6. 重启程序
Args:
installer_path: 安装包路径
@@ -187,16 +242,16 @@ def install_update_and_restart(installer_path):
exe_name
)
# 启动更新脚本(独立进程)
print(f"[Updater] 启动更新脚本: {update_script_path}")
subprocess.Popen(
['cmd', '/c', update_script_path],
creationflags=subprocess.CREATE_NO_WINDOW | subprocess.DETACHED_PROCESS,
close_fds=True
)
# 🔥 关键修复以管理员身份启动批处理脚本提前触发UAC
print(f"[Updater] 以管理员身份启动更新脚本: {update_script_path}")
success = run_as_admin(update_script_path)
print(f"[Updater] ✅ 更新脚本已启动")
return True
if success:
print(f"[Updater] ✅ 更新脚本已以管理员身份启动")
return True
else:
print(f"[Updater] ❌ 用户取消了UAC授权更新已取消")
return False
except Exception as e:
print(f"[Updater] ❌ 启动更新失败: {e}")
@@ -231,65 +286,67 @@ def create_update_installer_script(installer_path, install_dir, exe_name):
install_dir = os.path.abspath(install_dir)
script_content = f"""@echo off
chcp 65001 > nul
title 水滴AI客服智能助手 - 自动更新
REM ShuiDi AI Assistant Auto Update Script
REM Encoding: UTF-8 BOM
title ShuiDi AI Assistant - Auto Update
echo ============================================
echo 水滴AI客服智能助手 - 自动更新
echo ShuiDi AI Assistant Auto Update
echo ============================================
echo.
REM 切换到程序目录
REM Change to program directory
cd /d "{install_dir}"
echo [INFO] 程序目录: {install_dir}
echo INFO: Program directory: {install_dir}
echo.
REM 等待主程序退出最多等待30秒
echo [INFO] 等待主程序退出...
REM Wait for main program to exit (max 60 seconds)
echo INFO: Waiting for main program to exit...
set count=0
:wait_main_exit
tasklist /FI "IMAGENAME eq {exe_name}" 2>NUL | find /I "{exe_name}" >NUL
if NOT ERRORLEVEL 1 (
if %count% LSS 30 (
if %count% LSS 60 (
timeout /t 1 /nobreak > nul
set /a count+=1
goto wait_main_exit
) else (
echo [WARN] 主程序未正常退出,强制继续安装
echo WARN: Main program did not exit normally, forcing installation
)
)
echo [OK] 主程序已退出
echo OK: Main program exited
echo.
REM 执行静默安装(在当前目录下)
echo [INFO] 开始安装更新...
echo [INFO] 安装包: "{installer_path}"
echo [INFO] 目标目录: "{install_dir}"
REM Execute NSIS silent installation
echo INFO: Starting installation...
echo INFO: Installer: "{installer_path}"
echo INFO: Target directory: "{install_dir}"
echo.
REM 使用完整路径和引号避免空格问题
"{installer_path}" /S /D="{install_dir}"
REM Execute installation (with admin rights from NSIS)
"{installer_path}" /S /D={install_dir}
REM 等待安装完成
echo [INFO] 等待安装完成...
timeout /t 20 /nobreak > nul
REM Wait for installation to complete
echo INFO: Waiting for installation to complete...
timeout /t 25 /nobreak > nul
REM 清理安装包
echo [INFO] 清理安装包...
REM Cleanup installer
echo INFO: Cleaning up installer...
del /f /q "{installer_path}" 2>nul
REM 启动新版本程序
echo [INFO] 正在启动新版本...
REM Start new version
echo INFO: Starting new version...
if exist "{install_dir}\\{exe_name}" (
start "" "{install_dir}\\{exe_name}"
echo [OK] ✅ 程序已启动
echo OK: Program started successfully
) else (
echo [ERROR] ❌ 找不到程序文件: {exe_name}
echo [INFO] 请手动启动程序
echo ERROR: Program file not found: {exe_name}
echo INFO: Please start program manually
pause
)
REM 延迟后删除自己
REM Delete this script after delay
timeout /t 2 /nobreak > nul
del /f /q "%~f0" 2>nul
exit