210 lines
8.5 KiB
Python
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() |