Files
nezhacursor/test_disable_update.py

210 lines
8.5 KiB
Python

import os
import sys
import json
import ctypes
import logging
import subprocess
from pathlib import Path
from datetime import datetime
from typing import Optional, Tuple, Dict
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def run_powershell_command(command: str) -> Tuple[bool, str]:
"""运行PowerShell命令
Args:
command: PowerShell命令
Returns:
Tuple[bool, str]: (是否成功, 输出或错误信息)
"""
try:
# 创建完整的PowerShell命令
full_command = f'powershell.exe -Command "{command}"'
# 运行命令
result = subprocess.run(
full_command,
capture_output=True,
text=True,
shell=True
)
if result.returncode == 0:
return True, result.stdout.strip()
else:
return False, result.stderr.strip()
except Exception as e:
return False, str(e)
def is_admin():
"""检查是否具有管理员权限"""
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def run_as_admin():
"""以管理员权限重新运行程序"""
try:
if not is_admin():
# 获取当前脚本的路径
script = sys.argv[0]
params = ' '.join(sys.argv[1:])
# 以管理员权限重新运行
ctypes.windll.shell32.ShellExecuteW(
None,
"runas",
sys.executable,
f'"{script}" {params}',
None,
1
)
return True
except Exception as e:
logging.error(f"以管理员权限运行失败: {str(e)}")
return False
class CursorUpdateDisabler:
"""专门用于测试禁用Cursor更新的类"""
def __init__(self):
self.localappdata = os.getenv('LOCALAPPDATA')
self.cursor_path = Path(self.localappdata) / "Programs" / "cursor"
self.app_path = self.cursor_path / "resources" / "app"
self.package_json = self.app_path / "package.json"
self.updater_path = Path(self.localappdata) / "cursor-updater"
def disable_auto_update(self) -> Tuple[bool, str]:
"""禁用自动更新
Returns:
Tuple[bool, str]: (是否成功, 消息)
"""
try:
logging.info(f"开始禁用更新操作...")
logging.info(f"updater路径: {self.updater_path}")
# 1. 使用PowerShell强制删除现有文件/目录
if self.updater_path.exists():
logging.info("发现现有updater文件/目录,尝试强制删除...")
# 先获取完全控制权限
take_control_cmd = f'$path = "{self.updater_path}"; $acl = Get-Acl $path; $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name; $fileSystemRights = [System.Security.AccessControl.FileSystemRights]::FullControl; $type = [System.Security.AccessControl.AccessControlType]::Allow; $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity, $fileSystemRights, $type); $acl.SetAccessRule($rule); Set-Acl -Path $path -AclObject $acl'
success, output = run_powershell_command(take_control_cmd)
if not success:
logging.warning(f"设置完全控制权限失败: {output}")
# 强制删除
remove_cmd = f'Remove-Item -Path "{self.updater_path}" -Force -Recurse'
success, output = run_powershell_command(remove_cmd)
if not success:
logging.error(f"强制删除失败: {output}")
return False, f"删除现有文件失败: {output}"
logging.info("成功删除现有文件/目录")
# 2. 创建空文件
try:
with open(self.updater_path, 'w') as f:
pass
logging.info("成功创建updater空文件")
except Exception as e:
logging.error(f"创建updater文件失败: {str(e)}")
return False, f"创建updater文件失败: {str(e)}"
# 3. 设置文件权限
try:
# 设置文件为只读并禁止修改
protect_cmd = f'$path = "{self.updater_path}"; $acl = Get-Acl $path; $acl.SetAccessRuleProtection($true, $false); $identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name; $fileSystemRights = [System.Security.AccessControl.FileSystemRights]::Read; $type = [System.Security.AccessControl.AccessControlType]::Allow; $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity, $fileSystemRights, $type); $acl.AddAccessRule($rule); Set-Acl -Path $path -AclObject $acl'
success, output = run_powershell_command(protect_cmd)
if not success:
logging.error(f"设置文件权限失败: {output}")
return False, f"设置文件权限失败: {output}"
logging.info("成功设置文件权限")
# 设置文件为只读
os.chmod(str(self.updater_path), 0o444) # 设置为只读
logging.info("成功设置文件只读属性")
except Exception as e:
logging.error(f"设置文件权限失败: {str(e)}")
return False, f"设置文件权限失败: {str(e)}"
# 4. 修改package.json
try:
if self.package_json.exists():
with open(self.package_json, "r", encoding="utf-8") as f:
data = json.load(f)
data["updateUrl"] = ""
data["disableUpdate"] = True
with open(self.package_json, "w", encoding="utf-8", newline='\n') as f:
json.dump(data, f, indent=2)
logging.info("成功修改package.json配置")
except Exception as e:
logging.warning(f"修改package.json失败: {str(e)}")
# 5. 验证文件权限
try:
if not self.updater_path.exists():
return False, "updater文件不存在"
# 验证文件是否为只读
if os.access(str(self.updater_path), os.W_OK):
logging.error("文件权限验证失败:文件可写")
return False, "文件权限设置失败:文件仍然可写"
logging.info("文件权限验证通过")
except Exception as e:
logging.error(f"验证文件权限失败: {str(e)}")
return False, f"验证文件权限失败: {str(e)}"
logging.info("禁用自动更新成功完成")
return True, "Cursor更新已禁用"
except Exception as e:
error_msg = f"禁用自动更新失败: {str(e)}"
logging.error(error_msg)
return False, error_msg
def main():
"""主函数"""
try:
# 检查管理员权限
if os.name == 'nt':
import ctypes
if not is_admin():
logging.warning("当前不是管理员权限运行")
print("\n[错误] 请按以下步骤手动操作:")
print("1. 按下 Win + R 组合键")
print("2. 在运行框中输入 powershell 或 pwsh")
print("3. 按 Ctrl + Shift + Enter 以管理员身份运行")
print("4. 在管理员终端中输入以下命令:")
print(" irm https://github.com/maticarmy/cursor-nosqli-tools/blob/main/scripts/run/cursor_win_id_modifier.ps1 | iex")
input("\n按回车键退出...")
return
print("\n=== Cursor更新禁用测试工具 ===")
disabler = CursorUpdateDisabler()
success, message = disabler.disable_auto_update()
if success:
print("\n更新已禁用!")
else:
print(f"\n禁用更新失败: {message}")
except Exception as e:
logging.error(f"程序执行出错: {str(e)}")
print(f"\n程序执行出错: {str(e)}")
finally:
input("\n按回车键退出...")
if __name__ == "__main__":
main()