Files
tingquanzhushou/update_disabler.py
2025-02-20 20:20:19 +08:00

151 lines
5.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import sys
import sqlite3
import requests
import urllib3
import shutil
import subprocess
import stat
import getpass
import time
from datetime import datetime
from typing import Optional, Dict, Tuple
from logger import logger
class UpdateDisabler:
"""更新禁用模块"""
def __init__(self, updater_path: str = None):
"""
初始化更新禁用器
:param updater_path: 可选updater目录路径
"""
# 设置基础路径
localappdata = os.getenv('LOCALAPPDATA')
if not localappdata:
raise EnvironmentError("LOCALAPPDATA 环境变量未设置")
self.updater_path = updater_path or os.path.join(localappdata, 'cursor-updater')
self._callback = None
self.logger = logger.get_logger("UpdateDisable")
def set_progress_callback(self, callback) -> None:
"""设置进度回调函数"""
self._callback = callback
def _update_progress(self, status: str, message: str) -> None:
"""更新进度信息"""
if self._callback:
self._callback({"status": status, "message": message})
def _ensure_parent_dir_exists(self):
"""确保父目录存在"""
parent_dir = os.path.dirname(self.updater_path)
if not os.path.exists(parent_dir):
os.makedirs(parent_dir, exist_ok=True)
def disable(self) -> bool:
"""
禁用自动更新
:return: 是否成功
"""
try:
self._update_progress("start", "开始禁用自动更新...")
# 确保父目录存在
self._ensure_parent_dir_exists()
# 检查并删除现有文件或目录
self._update_progress("checking", "检查现有文件...")
try:
if os.path.exists(self.updater_path):
self._update_progress("removing", "删除现有文件...")
if os.path.isfile(self.updater_path):
os.remove(self.updater_path)
else:
shutil.rmtree(self.updater_path, ignore_errors=True)
self.logger.info(f"已删除: {self.updater_path}")
else:
self.logger.info("目标路径不存在,将创建新文件")
except Exception as e:
self.logger.warning(f"删除操作异常: {str(e)}")
# 等待文件系统操作完成
time.sleep(1)
# 创建阻止更新的文件
self._update_progress("creating", "创建阻止文件...")
try:
# 再次确保路径不存在
if os.path.exists(self.updater_path):
os.remove(self.updater_path)
# 创建新文件
with open(self.updater_path, 'w') as f:
f.write("")
self.logger.info("已创建阻止文件")
# 验证文件是否成功创建
if not os.path.isfile(self.updater_path):
raise Exception("文件创建验证失败")
except Exception as e:
raise Exception(f"创建文件失败: {str(e)}")
# 设置文件只读属性
self._update_progress("setting", "设置文件属性...")
try:
os.chmod(self.updater_path, stat.S_IREAD)
except Exception as e:
self.logger.warning(f"设置只读属性失败: {str(e)}")
# 设置文件权限
self._update_progress("permission", "设置文件权限...")
try:
username = getpass.getuser()
result = subprocess.run(
['icacls', self.updater_path, '/inheritance:r', '/grant:r', f"{username}:(R)"],
capture_output=True,
text=True
)
if result.returncode != 0:
self.logger.warning(f"设置权限返回值非0: {result.stderr}")
except Exception as e:
self.logger.warning(f"设置权限失败: {str(e)}")
# 最终验证
if not os.path.exists(self.updater_path):
raise Exception("最终验证失败:文件不存在")
if os.path.isdir(self.updater_path):
raise Exception("最终验证失败:创建了目录而不是文件")
self._update_progress("complete", "禁用自动更新完成")
self.logger.info("成功禁用自动更新")
return True
except Exception as e:
self.logger.error(f"禁用自动更新失败: {str(e)}")
self._update_progress("error", f"操作失败: {str(e)}")
self.show_manual_guide()
return False
def show_manual_guide(self) -> str:
"""
显示手动操作指南
:return: 指南内容
"""
guide = (
"自动禁用更新失败,请按以下步骤手动操作:\n"
"1. 以管理员身份打开 PowerShell\n"
"2. 执行以下命令:\n"
f" Remove-Item -Path \"{self.updater_path}\" -Force -Recurse -ErrorAction SilentlyContinue\n"
f" New-Item -Path \"{self.updater_path}\" -ItemType File -Force\n"
f" Set-ItemProperty -Path \"{self.updater_path}\" -Name IsReadOnly -Value $true\n"
f" icacls \"{self.updater_path}\" /inheritance:r /grant:r \"{getpass.getuser()}:(R)\""
)
self.logger.warning("需要手动禁用更新")
self.logger.info(guide)
return guide