Compare commits
2 Commits
b5cbf0779b
...
v3.3.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10523de040 | ||
|
|
dd0a307ff4 |
@@ -229,7 +229,17 @@ class AccountSwitcher:
|
||||
try:
|
||||
# 1. 先关闭所有Cursor进程
|
||||
if sys.platform == "win32":
|
||||
os.system("taskkill /f /im Cursor.exe >nul 2>&1")
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 使用subprocess.run来执行命令,并隐藏窗口
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe >nul 2>&1",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 清理注册表(包括更新系统 MachineGuid)
|
||||
@@ -284,7 +294,17 @@ class AccountSwitcher:
|
||||
try:
|
||||
# 1. 先关闭所有Cursor进程
|
||||
if sys.platform == "win32":
|
||||
os.system("taskkill /f /im Cursor.exe >nul 2>&1")
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 关闭Cursor
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe >nul 2>&1",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 重置机器码
|
||||
@@ -406,9 +426,19 @@ class AccountSwitcher:
|
||||
logging.info("正在重启Cursor...")
|
||||
if sys.platform == "win32":
|
||||
# Windows系统
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 关闭Cursor
|
||||
os.system("taskkill /f /im Cursor.exe 2>nul")
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe 2>nul",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 获取Cursor安装路径
|
||||
cursor_exe = self.cursor_path / "Cursor.exe"
|
||||
if cursor_exe.exists():
|
||||
@@ -421,16 +451,16 @@ class AccountSwitcher:
|
||||
return False
|
||||
elif sys.platform == "darwin":
|
||||
# macOS系统
|
||||
os.system("killall Cursor 2>/dev/null")
|
||||
subprocess.run("killall Cursor 2>/dev/null", shell=True)
|
||||
time.sleep(2)
|
||||
os.system("open -a Cursor")
|
||||
subprocess.run("open -a Cursor", shell=True)
|
||||
logging.info("Cursor重启成功")
|
||||
return True
|
||||
elif sys.platform == "linux":
|
||||
# Linux系统
|
||||
os.system("pkill -f cursor")
|
||||
subprocess.run("pkill -f cursor", shell=True)
|
||||
time.sleep(2)
|
||||
os.system("cursor &")
|
||||
subprocess.run("cursor &", shell=True)
|
||||
logging.info("Cursor重启成功")
|
||||
return True
|
||||
else:
|
||||
@@ -447,12 +477,7 @@ class AccountSwitcher:
|
||||
Tuple[bool, str]: (是否成功, 提示消息)
|
||||
"""
|
||||
try:
|
||||
# 1. 先关闭所有Cursor进程
|
||||
if sys.platform == "win32":
|
||||
os.system("taskkill /f /im Cursor.exe >nul 2>&1")
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 获取未使用的账号
|
||||
# 1. 获取未使用的账号
|
||||
endpoint = "https://cursorapi.nosqli.com/admin/api.account/getUnused"
|
||||
data = {
|
||||
"machine_id": self.hardware_id
|
||||
@@ -504,11 +529,26 @@ class AccountSwitcher:
|
||||
if not all([email, access_token, refresh_token]):
|
||||
return False, "获取账号信息不完整"
|
||||
|
||||
# 2. 先关闭Cursor进程
|
||||
if sys.platform == "win32":
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 使用subprocess.run来执行命令,并隐藏窗口
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe >nul 2>&1",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 3. 更新Cursor认证信息
|
||||
if not self.auth_manager.update_auth(email, access_token, refresh_token):
|
||||
return False, "更新Cursor认证信息失败"
|
||||
|
||||
# 4. 重置机器码(包含了清理注册表、文件和重启操作)
|
||||
# 4. 重置机器码(使用现有的reset_machine_id方法)
|
||||
if not self.reset_machine_id():
|
||||
return False, "重置机器码失败"
|
||||
|
||||
@@ -546,7 +586,17 @@ class AccountSwitcher:
|
||||
try:
|
||||
# 1. 先关闭所有Cursor进程
|
||||
if sys.platform == "win32":
|
||||
os.system("taskkill /f /im Cursor.exe >nul 2>&1")
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 关闭Cursor
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe >nul 2>&1",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 删除updater目录并创建同名文件以阻止更新
|
||||
|
||||
53
build.bat
53
build.bat
@@ -5,8 +5,61 @@ echo 开始打包流程...
|
||||
:: 更新版本号
|
||||
python update_version.py
|
||||
|
||||
:: 读取版本号
|
||||
set /p VERSION=<version.txt
|
||||
echo 当前版本: %VERSION%
|
||||
|
||||
:: 提取主版本号和次版本号 (3.4.4 -> 3.4)
|
||||
for /f "tokens=1,2 delims=." %%a in ("%VERSION%") do (
|
||||
set MAJOR_VERSION=%%a.%%b
|
||||
)
|
||||
echo 主版本目录: %MAJOR_VERSION%
|
||||
|
||||
:: 创建版本目录
|
||||
set VERSION_DIR=dist\%MAJOR_VERSION%
|
||||
if not exist "%VERSION_DIR%" (
|
||||
mkdir "%VERSION_DIR%"
|
||||
echo 创建目录: %VERSION_DIR%
|
||||
)
|
||||
|
||||
:: 使用新的spec文件进行打包
|
||||
pyinstaller --noconfirm build_nezha.spec
|
||||
|
||||
:: 检查源文件是否存在
|
||||
echo 检查文件: dist\听泉cursor助手%VERSION%.exe
|
||||
if not exist "dist\听泉cursor助手%VERSION%.exe" (
|
||||
echo 错误: 打包后的文件不存在
|
||||
echo 预期文件路径: dist\听泉cursor助手%VERSION%.exe
|
||||
dir /b dist
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: 检查目标目录是否存在
|
||||
echo 检查目标目录: %VERSION_DIR%
|
||||
if not exist "%VERSION_DIR%" (
|
||||
echo 错误: 目标目录不存在
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: 移动文件到版本目录
|
||||
echo 移动文件:
|
||||
echo 源文件: dist\听泉cursor助手%VERSION%.exe
|
||||
echo 目标文件: %VERSION_DIR%\听泉cursor助手v%VERSION%.exe
|
||||
move "dist\听泉cursor助手%VERSION%.exe" "%VERSION_DIR%\听泉cursor助手v%VERSION%.exe"
|
||||
if errorlevel 1 (
|
||||
echo 移动文件失败,请检查:
|
||||
echo 1. 源文件是否存在: dist\听泉cursor助手%VERSION%.exe
|
||||
echo 2. 目标目录是否可写: %VERSION_DIR%
|
||||
echo 3. 目标文件是否已存在: %VERSION_DIR%\听泉cursor助手v%VERSION%.exe
|
||||
dir /b dist
|
||||
dir /b "%VERSION_DIR%"
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 打包完成!
|
||||
echo 文件保存在: %VERSION_DIR%\听泉cursor助手v%VERSION%.exe
|
||||
pause
|
||||
@@ -5,6 +5,7 @@ import time
|
||||
import logging
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
class CursorAuthManager:
|
||||
"""Cursor认证信息管理器"""
|
||||
@@ -99,9 +100,19 @@ class CursorAuthManager:
|
||||
logging.info("正在重启Cursor...")
|
||||
if sys.platform == "win32":
|
||||
# Windows系统
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 关闭Cursor
|
||||
os.system("taskkill /f /im Cursor.exe 2>nul")
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe 2>nul",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 获取Cursor安装路径
|
||||
cursor_exe = self.cursor_path / "Cursor.exe"
|
||||
if cursor_exe.exists():
|
||||
@@ -114,16 +125,16 @@ class CursorAuthManager:
|
||||
return False
|
||||
elif sys.platform == "darwin":
|
||||
# macOS系统
|
||||
os.system("killall Cursor 2>/dev/null")
|
||||
subprocess.run("killall Cursor 2>/dev/null", shell=True)
|
||||
time.sleep(2)
|
||||
os.system("open -a Cursor")
|
||||
subprocess.run("open -a Cursor", shell=True)
|
||||
logging.info("Cursor重启成功")
|
||||
return True
|
||||
elif sys.platform == "linux":
|
||||
# Linux系统
|
||||
os.system("pkill -f cursor")
|
||||
subprocess.run("pkill -f cursor", shell=True)
|
||||
time.sleep(2)
|
||||
os.system("cursor &")
|
||||
subprocess.run("cursor &", shell=True)
|
||||
logging.info("Cursor重启成功")
|
||||
return True
|
||||
else:
|
||||
|
||||
@@ -12,6 +12,7 @@ from PyQt5.QtGui import QIcon, QPixmap
|
||||
import time
|
||||
import requests
|
||||
from urllib.parse import quote
|
||||
import subprocess
|
||||
|
||||
sys.path.append(str(Path(__file__).parent.parent))
|
||||
|
||||
@@ -1340,7 +1341,17 @@ class MainWindow(QMainWindow):
|
||||
try:
|
||||
# 1. 先关闭所有Cursor进程
|
||||
if sys.platform == "win32":
|
||||
os.system("taskkill /f /im Cursor.exe >nul 2>&1")
|
||||
# 创建startupinfo对象来隐藏命令行窗口
|
||||
startupinfo = subprocess.STARTUPINFO()
|
||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||
startupinfo.wShowWindow = subprocess.SW_HIDE
|
||||
|
||||
# 关闭Cursor
|
||||
subprocess.run(
|
||||
"taskkill /f /im Cursor.exe >nul 2>&1",
|
||||
startupinfo=startupinfo,
|
||||
shell=True
|
||||
)
|
||||
time.sleep(2)
|
||||
|
||||
# 2. 处理updater文件
|
||||
@@ -1628,7 +1639,7 @@ class MainWindow(QMainWindow):
|
||||
self.show_custom_message(
|
||||
"检查更新",
|
||||
"已是最新版本",
|
||||
"您当前使用的已经是最新版本。",
|
||||
f"您当前使用的 v{self.version_manager.current_version} 已经是最新版本。",
|
||||
QStyle.SP_DialogApplyButton,
|
||||
"#198754"
|
||||
)
|
||||
@@ -1682,7 +1693,8 @@ class MainWindow(QMainWindow):
|
||||
version_layout.addWidget(current_version_label)
|
||||
|
||||
# 最新版本
|
||||
new_version_label = QLabel(f"最新版本:v{version_info.get('version_no', '未知')} ({version_info.get('version_name', '未知')})")
|
||||
new_version = version_info.get('version_no', '未知').lstrip('v')
|
||||
new_version_label = QLabel(f"最新版本:v{new_version} ({version_info.get('version_name', '未知')})")
|
||||
new_version_label.setStyleSheet("font-weight: bold; color: #0d6efd;")
|
||||
version_layout.addWidget(new_version_label)
|
||||
|
||||
|
||||
@@ -12,6 +12,12 @@ REM 读取当前版本号
|
||||
set /p VERSION=<version.txt
|
||||
echo 当前正式版本: %VERSION%
|
||||
|
||||
REM 提取主版本号和次版本号 (3.4.4 -> 3.4)
|
||||
for /f "tokens=1,2 delims=." %%a in ("%VERSION%") do (
|
||||
set MAJOR_VERSION=%%a.%%b
|
||||
)
|
||||
echo 主版本目录: %MAJOR_VERSION%
|
||||
|
||||
REM 读取测试版本号(如果存在)
|
||||
if exist testversion.txt (
|
||||
set /p TEST_VERSION=<testversion.txt
|
||||
@@ -29,7 +35,11 @@ set FULL_VERSION=%VERSION%.!TEST_VERSION!
|
||||
echo 完整版本号: !FULL_VERSION!
|
||||
|
||||
REM 创建测试版本输出目录
|
||||
if not exist "dist\test" mkdir "dist\test"
|
||||
set TEST_DIR=dist\test\%MAJOR_VERSION%
|
||||
if not exist "!TEST_DIR!" (
|
||||
mkdir "!TEST_DIR!"
|
||||
echo 创建目录: !TEST_DIR!
|
||||
)
|
||||
|
||||
REM 清理旧文件
|
||||
if exist "dist\听泉cursor助手%VERSION%.exe" del "dist\听泉cursor助手%VERSION%.exe"
|
||||
@@ -38,13 +48,36 @@ if exist "build" rmdir /s /q "build"
|
||||
REM 执行打包
|
||||
venv\Scripts\python.exe -m PyInstaller build_nezha.spec --clean
|
||||
|
||||
REM 检查源文件是否存在
|
||||
echo 检查文件: dist\听泉cursor助手%VERSION%.exe
|
||||
if not exist "dist\听泉cursor助手%VERSION%.exe" (
|
||||
echo 错误: 打包后的文件不存在
|
||||
echo 预期文件路径: dist\听泉cursor助手%VERSION%.exe
|
||||
dir /b dist
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 移动并重命名文件
|
||||
move "dist\听泉cursor助手%VERSION%.exe" "dist\test\听泉cursor助手v!FULL_VERSION!.exe"
|
||||
echo 移动文件:
|
||||
echo 源文件: dist\听泉cursor助手%VERSION%.exe
|
||||
echo 目标文件: !TEST_DIR!\听泉cursor助手v!FULL_VERSION!.exe
|
||||
move "dist\听泉cursor助手%VERSION%.exe" "!TEST_DIR!\听泉cursor助手v!FULL_VERSION!.exe"
|
||||
if errorlevel 1 (
|
||||
echo 移动文件失败,请检查:
|
||||
echo 1. 源文件是否存在: dist\听泉cursor助手%VERSION%.exe
|
||||
echo 2. 目标目录是否可写: !TEST_DIR!
|
||||
echo 3. 目标文件是否已存在: !TEST_DIR!\听泉cursor助手v!FULL_VERSION!.exe
|
||||
dir /b dist
|
||||
dir /b "!TEST_DIR!"
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
echo.
|
||||
echo 测试版本构建完成!
|
||||
echo 版本号: v!FULL_VERSION!
|
||||
echo 文件位置: dist\test\听泉cursor助手v!FULL_VERSION!.exe
|
||||
echo 文件位置: !TEST_DIR!\听泉cursor助手v!FULL_VERSION!.exe
|
||||
|
||||
REM 退出虚拟环境
|
||||
deactivate
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import Optional, Dict, Any
|
||||
import json
|
||||
import logging
|
||||
from urllib.parse import quote, unquote
|
||||
from pathlib import Path
|
||||
|
||||
class VersionManager:
|
||||
"""版本管理器
|
||||
@@ -20,15 +21,25 @@ class VersionManager:
|
||||
|
||||
def __init__(self):
|
||||
self.base_url = "https://cursorapi.nosqli.com"
|
||||
# 获取项目根目录路径
|
||||
self.root_path = Path(__file__).parent.parent
|
||||
self.current_version = self._get_current_version()
|
||||
self.platform = "windows" if sys.platform.startswith("win") else "mac" if sys.platform.startswith("darwin") else "linux"
|
||||
|
||||
def _get_current_version(self) -> str:
|
||||
"""获取当前版本号"""
|
||||
try:
|
||||
with open("version.txt", "r") as f:
|
||||
return f.read().strip()
|
||||
except FileNotFoundError:
|
||||
version_file = self.root_path / "version.txt"
|
||||
if not version_file.exists():
|
||||
logging.error(f"版本文件不存在: {version_file}")
|
||||
return "0.0.0"
|
||||
|
||||
with open(version_file, "r", encoding="utf-8") as f:
|
||||
version = f.read().strip()
|
||||
logging.info(f"当前版本: {version}")
|
||||
return version
|
||||
except Exception as e:
|
||||
logging.error(f"读取版本号失败: {str(e)}")
|
||||
return "0.0.0"
|
||||
|
||||
def _handle_response(self, response: requests.Response) -> Dict[str, Any]:
|
||||
@@ -82,8 +93,10 @@ class VersionManager:
|
||||
"""检查是否有更新"""
|
||||
try:
|
||||
url = f"{self.base_url}/admin/api.version/check"
|
||||
current_version = self.current_version.lstrip('v') # 移除可能存在的v前缀
|
||||
|
||||
params = {
|
||||
"version": self.current_version,
|
||||
"version": current_version,
|
||||
"platform": self.platform
|
||||
}
|
||||
logging.info(f"正在请求: {url}")
|
||||
@@ -99,7 +112,19 @@ class VersionManager:
|
||||
logging.info(f"响应头: {dict(response.headers)}")
|
||||
logging.info(f"响应内容: {response.text}")
|
||||
|
||||
return self._handle_response(response)
|
||||
result = self._handle_response(response)
|
||||
|
||||
# 确保返回的数据包含版本信息
|
||||
if result["code"] == 0 and result.get("data"):
|
||||
data = result["data"]
|
||||
if "version_info" in data:
|
||||
version_info = data["version_info"]
|
||||
# 确保版本号格式一致
|
||||
if "version_no" in version_info:
|
||||
version_info["version_no"] = version_info["version_no"].lstrip('v')
|
||||
|
||||
return result
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
logging.error("检查更新超时")
|
||||
return {"code": -1, "msg": "请求超时,请检查网络连接", "data": None}
|
||||
@@ -145,15 +170,28 @@ class VersionManager:
|
||||
Returns:
|
||||
tuple: (是否有更新, 是否强制更新, 版本信息)
|
||||
"""
|
||||
result = self.check_update()
|
||||
if result["code"] == 0 and result["data"]:
|
||||
data = result["data"]
|
||||
return (
|
||||
data["has_update"],
|
||||
bool(data.get("is_force")),
|
||||
data.get("version_info")
|
||||
)
|
||||
return False, False, None
|
||||
try:
|
||||
result = self.check_update()
|
||||
if result["code"] == 0 and result["data"]:
|
||||
data = result["data"]
|
||||
version_info = data.get("version_info", {})
|
||||
|
||||
# 比较版本号(移除v前缀)
|
||||
current = self.current_version.lstrip('v')
|
||||
latest = version_info.get("version_no", "0.0.0").lstrip('v')
|
||||
|
||||
# 使用packaging.version进行版本比较
|
||||
has_update = version.parse(latest) > version.parse(current)
|
||||
|
||||
return (
|
||||
has_update,
|
||||
bool(data.get("is_force")),
|
||||
version_info
|
||||
)
|
||||
return False, False, None
|
||||
except Exception as e:
|
||||
logging.error(f"检查更新失败: {str(e)}")
|
||||
return False, False, None
|
||||
|
||||
def download_update(self, download_url: str, save_path: str) -> tuple[bool, str]:
|
||||
"""下载更新文件
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.4.2
|
||||
3.4.5
|
||||
Reference in New Issue
Block a user