4 Commits

Author SHA1 Message Date
huangzhenpc
207c3c604e v3.3.9版本更新: 1.优化UI界面和按钮样式 2.改进使用说明文字,增加颜色标注 3.优化加载对话框样式 4.添加请求节流机制,防止重复提交 5.完善错误处理和提示信息 6.优化会员状态检查逻辑 7.改进禁用更新功能的实现 2025-02-12 21:15:58 +08:00
huangzhenpc
4e11deb530 优化界面提示:1. 统一所有提示框样式,使用自定义美观对话框 2. 添加复制按钮功能,方便用户操作 3. 优化未激活会员时的提示信息展示 2025-02-12 14:57:23 +08:00
huangzhenpc
4531f12c0d feat: 优化GUI界面和用户体验
1. 优化按钮样式和布局:增加按钮尺寸和内边距,使用不同颜色区分功能按钮,添加按钮悬停和点击效果,优化按钮间距和对齐方式

2. 添加会员状态检查:实现状态缓存机制减少API请求,添加状态自动更新定时器,根据剩余时间动态调整更新间隔

3. 改进加载提示:添加加载对话框组件,实现异步API请求机制,优化加载状态显示

4. 优化购买提示界面:美化提示框样式和排版,添加多个购买渠道信息,优化文本对齐和间距

5. 其他改进:修复tkinter相关打包问题,优化错误提示信息,改进日志记录,完善异常处理
2025-02-12 14:39:50 +08:00
huangzhenpc
e3058b9e39 feat: 完成PyQt5 GUI实现,支持系统托盘和图标显示
1. 实现了基于PyQt5的GUI界面 2. 添加系统托盘功能,支持最小化到托盘 3. 修复了图标显示问题,包括窗口图标和任务栏图标 4. 优化了打包配置,支持PyInstaller打包 5. 版本更新到v3.3.1
2025-02-12 14:18:08 +08:00
16 changed files with 1272 additions and 1392 deletions

View File

@@ -50,9 +50,41 @@ class AccountSwitcher:
self.package_json = self.app_path / "package.json"
self.auth_manager = CursorAuthManager()
self.config = Config()
self.hardware_id = get_hardware_id()
self.hardware_id = self.get_hardware_id() # 先获取硬件ID
self.registry = CursorRegistry() # 添加注册表操作工具类
logging.info(f"初始化硬件ID: {self.hardware_id}")
def get_hardware_id(self) -> str:
"""获取硬件唯一标识"""
try:
# 创建startupinfo对象来隐藏命令行窗口
startupinfo = None
if sys.platform == "win32":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
# 获取CPU信息
cpu_info = subprocess.check_output('wmic cpu get ProcessorId', startupinfo=startupinfo).decode()
cpu_id = cpu_info.split('\n')[1].strip()
# 获取主板序列号
board_info = subprocess.check_output('wmic baseboard get SerialNumber', startupinfo=startupinfo).decode()
board_id = board_info.split('\n')[1].strip()
# 获取BIOS序列号
bios_info = subprocess.check_output('wmic bios get SerialNumber', startupinfo=startupinfo).decode()
bios_id = bios_info.split('\n')[1].strip()
# 组合信息并生成哈希
combined = f"{cpu_id}:{board_id}:{bios_id}"
return hashlib.md5(combined.encode()).hexdigest()
except Exception as e:
logging.error(f"获取硬件ID失败: {str(e)}")
# 如果获取失败使用UUID作为备选方案
return str(uuid.uuid4())
def get_cursor_version(self) -> str:
"""获取Cursor版本号"""
try:
@@ -71,199 +103,103 @@ class AccountSwitcher:
import platform
import socket
import requests
import subprocess
# 获取操作系统信息
os_info = f"{platform.system()} {platform.version()}"
os_info = f"{platform.system()} {platform.release()}"
# 获取设备名称
device_name = platform.node()
# 获取地理位置(可选)
try:
ip_info = requests.get('https://ipapi.co/json/', timeout=5).json()
# 在Windows上使用wmic获取更详细的计算机名称
if platform.system() == "Windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
computer_info = subprocess.check_output('wmic computersystem get model', startupinfo=startupinfo).decode()
device_name = computer_info.split('\n')[1].strip()
else:
device_name = platform.node()
except:
device_name = platform.node()
# 获取IP地址
try:
ip_response = requests.get('https://api.ipify.org?format=json', timeout=5)
ip_address = ip_response.json()['ip']
except:
ip_address = "未知"
# 获取地理位置
try:
ip_info = requests.get(f'https://ipapi.co/{ip_address}/json/', timeout=5).json()
location = f"{ip_info.get('country_name', '')}-{ip_info.get('region', '')}-{ip_info.get('city', '')}"
except:
location = ""
location = "未知"
return {
"os": os_info,
"device_name": device_name,
"ip": ip_address,
"location": location
}
except Exception as e:
logging.error(f"获取设备信息失败: {str(e)}")
return {
"os": "Windows 10",
"os": "Windows",
"device_name": "未知设备",
"location": ""
"ip": "未知",
"location": "未知"
}
def check_activation_code(self, code: str) -> Tuple[bool, str, Optional[Dict]]:
"""验证激活码
def check_activation_code(self, code: str) -> tuple:
"""检查激活码
Args:
code: 激活码
Returns:
Tuple[bool, str, Optional[Dict]]: (是否成功, 提示消息, 账号信息)
tuple: (成功标志, 消息, 账号信息)
"""
try:
# 获取当前状态和历史记录
member_info = self.config.load_member_info()
activation_history = member_info.get("activation_records", []) if member_info else []
data = {
"machine_id": self.hardware_id,
"code": code
}
# 分割多个激活码
codes = [c.strip() for c in code.split(',')]
success_codes = []
failed_codes = []
activation_results = []
# 获取设备信息
device_info = self.get_device_info()
# 逐个验证激活码
for single_code in codes:
if not single_code:
continue
# 验证激活码
endpoint = "https://cursorapi.nosqli.com/admin/api.member/activate"
data = {
"code": single_code,
"machine_id": self.hardware_id,
"os": device_info["os"],
"device_name": device_info["device_name"],
"location": device_info["location"]
response = requests.post(
self.config.get_api_url("activate"),
json=data,
headers={"Content-Type": "application/json"},
timeout=10
)
result = response.json()
if result["code"] == 200:
api_data = result["data"]
# 构造标准的返回数据结构
account_info = {
"status": "active",
"expire_time": api_data.get("expire_time", ""),
"total_days": api_data.get("total_days", 0),
"days_left": api_data.get("days_left", 0),
"device_info": self.get_device_info()
}
headers = {
"Content-Type": "application/json"
}
try:
response = requests.post(
endpoint,
json=data,
headers=headers,
timeout=10
)
response_data = response.json()
if response_data.get("code") == 200:
result_data = response_data.get("data", {})
logging.info(f"激活码 {single_code} 验证成功: {response_data.get('msg', '')}")
activation_results.append(result_data)
success_codes.append(single_code)
elif response_data.get("code") == 400:
error_msg = response_data.get("msg", "参数错误")
if "已被使用" in error_msg or "已激活" in error_msg:
logging.warning(f"激活码 {single_code} 已被使用")
failed_codes.append(f"{single_code} (已被使用)")
else:
logging.error(f"激活码 {single_code} 验证失败: {error_msg}")
failed_codes.append(f"{single_code} ({error_msg})")
elif response_data.get("code") == 500:
error_msg = response_data.get("msg", "系统错误")
logging.error(f"激活码 {single_code} 验证失败: {error_msg}")
failed_codes.append(f"{single_code} ({error_msg})")
else:
error_msg = response_data.get("msg", "未知错误")
logging.error(f"激活码 {single_code} 验证失败: {error_msg}")
failed_codes.append(f"{single_code} ({error_msg})")
except requests.RequestException as e:
logging.error(f"激活码 {single_code} 请求失败: {str(e)}")
failed_codes.append(f"{single_code} (网络请求失败)")
except Exception as e:
logging.error(f"激活码 {single_code} 处理失败: {str(e)}")
failed_codes.append(f"{single_code} (处理失败)")
if not success_codes:
failed_msg = "\n".join(failed_codes)
return False, f"激活失败:\n{failed_msg}", None
try:
# 使用最后一次激活的结果作为最终状态
final_result = activation_results[-1]
# 合并历史记录
new_activation_records = final_result.get("activation_records", [])
if activation_history:
# 保留旧的激活记录,避免重复
existing_codes = {record.get("code") for record in activation_history}
for record in new_activation_records:
if record.get("code") not in existing_codes:
activation_history.append(record)
else:
activation_history = new_activation_records
# 保存会员信息,包含完整的历史记录
member_info = {
"hardware_id": final_result.get("machine_id", self.hardware_id),
"expire_time": final_result.get("expire_time", ""),
"days_left": final_result.get("days_left", 0),
"total_days": final_result.get("total_days", 0),
"status": final_result.get("status", "inactive"),
"device_info": final_result.get("device_info", device_info),
"activation_time": final_result.get("activation_time", ""),
"activation_records": activation_history # 使用合并后的历史记录
}
self.config.save_member_info(member_info)
# 生成结果消息
message = f"激活成功\n"
# 显示每个成功激活码的信息
for i, result in enumerate(activation_results, 1):
message += f"\n{i}个激活码:\n"
message += f"- 新增天数: {result.get('added_days', 0)}\n"
activation_time = result.get('activation_time', '')
if activation_time:
try:
from datetime import datetime
dt = datetime.strptime(activation_time, "%Y-%m-%d %H:%M:%S")
activation_time = dt.strftime("%Y-%m-%d %H:%M:%S")
except:
pass
message += f"- 激活时间: {activation_time}\n"
message += f"\n最终状态:"
message += f"\n- 总天数: {final_result.get('total_days', 0)}"
message += f"\n- 剩余天数: {final_result.get('days_left', 0)}"
# 格式化到期时间显示
expire_time = final_result.get('expire_time', '')
if expire_time:
try:
dt = datetime.strptime(expire_time, "%Y-%m-%d %H:%M:%S")
expire_time = dt.strftime("%Y-%m-%d %H:%M:%S")
except:
pass
message += f"\n- 到期时间: {expire_time}"
# 显示完整的激活记录历史
message += "\n\n历史激活记录:"
for record in activation_history:
activation_time = record.get('activation_time', '')
if activation_time:
try:
dt = datetime.strptime(activation_time, "%Y-%m-%d %H:%M:%S")
activation_time = dt.strftime("%Y-%m-%d %H:%M:%S")
except:
pass
message += f"\n- 激活码: {record.get('code', '')}"
message += f"\n 天数: {record.get('days', 0)}"
message += f"\n 时间: {activation_time}\n"
if failed_codes:
message += f"\n\n以下激活码验证失败:\n" + "\n".join(failed_codes)
return True, message, member_info
except Exception as e:
logging.error(f"处理激活结果时出错: {str(e)}")
return False, f"处理激活结果时出错: {str(e)}", None
return True, result["msg"], account_info
return False, result["msg"], {
"status": "inactive",
"expire_time": "",
"total_days": 0,
"days_left": 0,
"device_info": self.get_device_info()
}
except Exception as e:
logging.error(f"验证激活码时出错: {str(e)}")
return False, f"验证激活码时出错: {str(e)}", None
return False, f"激活失败: {str(e)}", {
"status": "inactive",
"expire_time": "",
"total_days": 0,
"days_left": 0,
"device_info": self.get_device_info()
}
def reset_machine_id(self) -> bool:
"""重置机器码"""
@@ -356,93 +292,76 @@ class AccountSwitcher:
logging.error(f"激活过程出错: {str(e)}")
return False, f"激活失败: {str(e)}"
def get_member_status(self) -> Optional[Dict]:
def get_member_status(self) -> dict:
"""获取会员状态
Returns:
Optional[Dict]: 会员状态信息
dict: 会员状态信息,包含:
- status: 状态(active/inactive/expired)
- expire_time: 到期时间
- total_days: 总天数
- days_left: 剩余天数
- device_info: 设备信息
"""
try:
# 读取保存的会员信息
member_info = self.config.load_member_info()
# 构造状态检查请求
endpoint = "https://cursorapi.nosqli.com/admin/api.member/status"
data = {
"machine_id": self.hardware_id
}
headers = {
"Content-Type": "application/json"
api_url = self.config.get_api_url("status")
logging.info(f"正在检查会员状态...")
logging.info(f"API URL: {api_url}")
logging.info(f"请求数据: {data}")
response = requests.post(
api_url,
json=data,
headers={"Content-Type": "application/json"},
timeout=10
)
result = response.json()
logging.info(f"状态检查响应: {result}")
if result.get("code") in [1, 200]: # 兼容两种响应码
api_data = result.get("data", {})
# 构造标准的返回数据结构
return {
"status": api_data.get("status", "inactive"),
"expire_time": api_data.get("expire_time", ""),
"total_days": api_data.get("total_days", 0),
"days_left": api_data.get("days_left", 0),
"device_info": self.get_device_info() # 添加设备信息
}
else:
error_msg = result.get("msg", "未知错误")
logging.error(f"获取状态失败: {error_msg}")
return {
"status": "inactive",
"expire_time": "",
"total_days": 0,
"days_left": 0,
"device_info": self.get_device_info()
}
except requests.exceptions.RequestException as e:
logging.error(f"API请求失败: {str(e)}")
return {
"status": "inactive",
"expire_time": "",
"total_days": 0,
"days_left": 0,
"device_info": self.get_device_info()
}
try:
response = requests.post(endpoint, json=data, headers=headers, timeout=10)
response_data = response.json()
if response_data.get("code") == 200:
# 正常状态
data = response_data.get("data", {})
status = data.get("status", "inactive")
# 构造会员信息
member_info = {
"hardware_id": data.get("machine_id", self.hardware_id),
"expire_time": data.get("expire_time", ""),
"days_left": data.get("days_left", 0), # 使用days_left
"total_days": data.get("total_days", 0), # 使用total_days
"status": status,
"activation_records": data.get("activation_records", []) # 保存激活记录
}
# 打印调试信息
logging.info(f"API返回数据: {data}")
logging.info(f"处理后的会员信息: {member_info}")
self.config.save_member_info(member_info)
return member_info
elif response_data.get("code") == 401:
# 未激活或已过期
logging.warning("会员未激活或已过期")
return self._get_inactive_status()
elif response_data.get("code") == 400:
# 参数错误
error_msg = response_data.get("msg", "参数错误")
logging.error(f"获取会员状态失败: {error_msg}")
return self._get_inactive_status()
elif response_data.get("code") == 500:
# 系统错误
error_msg = response_data.get("msg", "系统错误")
logging.error(f"获取会员状态失败: {error_msg}")
return self._get_inactive_status()
else:
# 其他未知错误
error_msg = response_data.get("msg", "未知错误")
logging.error(f"获取会员状态失败: {error_msg}")
return self._get_inactive_status()
except requests.RequestException as e:
logging.error(f"请求会员状态失败: {str(e)}")
return self._get_inactive_status()
except Exception as e:
logging.error(f"获取会员状态出错: {str(e)}")
return self._get_inactive_status()
def _get_inactive_status(self) -> Dict:
"""获取未激活状态的默认信息"""
return {
"hardware_id": self.hardware_id,
"expire_time": "",
"days": 0,
"total_days": 0,
"status": "inactive",
"last_activation": {},
"activation_records": []
}
logging.error(f"获取会员状态失败: {str(e)}")
return {
"status": "inactive",
"expire_time": "",
"total_days": 0,
"days_left": 0,
"device_info": self.get_device_info()
}
def restart_cursor(self) -> bool:
"""重启Cursor编辑器

View File

@@ -1,202 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc"
}
},
"storage_json": {
"telemetry.machineId": "758a7f7f7f79078f9f2c690514878ea3e8f064c0a49e837dd396db89df58429c",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": [
{
"backupFolder": "1739332115293"
}
]
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {
"1739332115293": "__default__profile__"
}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 170,
"statusBarHeight": 22,
"windowBorder": false
}
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "758a7f7f7f79078f9f2c690514878ea3e8f064c0a49e837dd396db89df58429c",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,216 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"updateUrl": "",
"disableUpdate": true,
"enableNodeApiUncaughtExceptionPolicy": true,
"nodeOptions": [
"--force-node-api-uncaught-exceptions-policy=true"
]
}
},
"storage_json": {
"telemetry.machineId": "b0cbb2d13ca4c983be40d31e010819f16adb3d6083598f1457094837bdaa3def",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": []
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 300,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": []
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "1deb25e7-cdd4-4367-a347-fba8b33b9b03"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 1980,
"modified_time": "2025-02-12T12:37:17.428609"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:17.371311"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:14.253083"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "b0cbb2d13ca4c983be40d31e010819f16adb3d6083598f1457094837bdaa3def",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,244 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc"
}
},
"storage_json": {
"telemetry.machineId": "31b3701f1790cdb754bd8a02bad4913a9f8a3f04c9e19c519996be8c7b8cb561",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
},
{
"folderUri": "file:///d%3A/W/python/003cursorapiadmin"
}
],
"emptyWindows": [
{
"backupFolder": "1739329218500"
},
{
"backupFolder": "1739329245089"
}
]
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__",
"file:///d%3A/W/python/003cursorapiadmin": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 170,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": [
{
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
{
"folder": "file:///d%3A/W/python/003cursorapiadmin",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\b6b8cfb24ed2ddb05d90d45cce5443e7",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
}
]
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "31b3701f1790cdb754bd8a02bad4913a9f8a3f04c9e19c519996be8c7b8cb561",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,216 +0,0 @@
{
"package_json": {
"C:\\Users\\huangzhen\\AppData\\Local\\Programs\\Cursor\\resources\\app\\package.json": {
"homepage": "https://cursor.so",
"author": {
"name": "Cursor AI, Inc.",
"email": "hiring@cursor.so"
},
"productName": "Cursor",
"description": "Cursor is an AI-first coding environment.",
"main": "./out/main.js",
"dependencies": {
"@todesktop/runtime": "=1.6.1",
"@electron/asar": "^3.2.3",
"@anysphere/file-service": "0.0.0-73d604b6",
"@microsoft/1ds-core-js": "^3.2.13",
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.5.0",
"@sentry/electron": "5.7.0",
"@sentry/node": "8.35.0",
"@types/semver": "^7.5.8",
"@vscode/deviceid": "^0.1.1",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.8",
"@vscode/proxy-agent": "^0.27.0",
"@vscode/ripgrep": "^1.15.10",
"@vscode/spdlog": "^0.15.0",
"@vscode/sqlite3": "5.1.8-vscode",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/tree-sitter-wasm": "^0.0.4",
"@vscode/vscode-languagedetection": "1.0.21",
"@vscode/windows-mutex": "^0.5.0",
"@vscode/windows-process-tree": "^0.6.0",
"@vscode/windows-registry": "^1.1.0",
"@xterm/addon-clipboard": "^0.2.0-beta.53",
"@xterm/addon-image": "^0.9.0-beta.70",
"@xterm/addon-ligatures": "^0.10.0-beta.70",
"@xterm/addon-search": "^0.16.0-beta.70",
"@xterm/addon-serialize": "^0.14.0-beta.70",
"@xterm/addon-unicode11": "^0.9.0-beta.70",
"@xterm/addon-webgl": "^0.19.0-beta.70",
"@xterm/headless": "^5.6.0-beta.70",
"@xterm/xterm": "^5.6.0-beta.70",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"jschardet": "3.1.4",
"kerberos": "2.1.1",
"minimist": "^1.2.6",
"multiformats": "^13.3.1",
"native-is-elevated": "0.7.0",
"native-keymap": "^3.3.5",
"native-watchdog": "^1.4.1",
"node-fetch": "2.7.0",
"node-pty": "1.1.0-beta22",
"open": "^8.4.2",
"tas-client-umd": "0.2.0",
"v8-inspect-profiler": "^0.1.1",
"vscode-oniguruma": "1.7.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "9.1.0",
"yauzl": "^3.0.0",
"yazl": "^2.4.3"
},
"name": "cursor",
"version": "0.45.11",
"type": "module",
"desktopName": "cursor-url-handler.desktop",
"overrides": {},
"tdBuildId": "250207y6nbaw5qc",
"email": "jrxqnsoz250264@nosqli.com",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSktTUEJLQlIxOTNKMjY3RENSVDRTR1YyIiwidGltZSI6IjE3MzkyNTAzNDgiLCJyYW5kb21uZXNzIjoiYWIyNWVhYTYtNDQzZC00Y2Q0IiwiZXhwIjo0MzMxMjUwMzQ4LCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.f3VIttCJLWqhkEZpPmWJlYw32FuV_gLWl9E0N-O9oIc",
"updateUrl": "",
"disableUpdate": true,
"enableNodeApiUncaughtExceptionPolicy": true,
"nodeOptions": [
"--force-node-api-uncaught-exceptions-policy=true"
]
}
},
"storage_json": {
"telemetry.machineId": "9eb67b11924f32572a67e6480ce4f1cabf3f61503aa4918af506b259527a4745",
"telemetry.macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"telemetry.sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}",
"telemetry.devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"backupWorkspaces": {
"workspaces": [],
"folders": [
{
"folderUri": "file:///d%3A/W/python/001cursro.app/interactive"
}
],
"emptyWindows": []
},
"windowControlHeight": 35,
"profileAssociations": {
"workspaces": {
"file:///d%3A/W/python/001cursro.app/interactive": "__default__profile__"
},
"emptyWindows": {}
},
"theme": "vs-dark",
"themeBackground": "#1f1f1f",
"windowSplash": {
"zoomLevel": 0,
"baseTheme": "vs-dark",
"colorInfo": {
"foreground": "#cccccc",
"background": "#1f1f1f",
"editorBackground": "#1f1f1f",
"titleBarBackground": "#181818",
"titleBarBorder": "#2b2b2b",
"activityBarBackground": "#181818",
"activityBarBorder": "#2b2b2b",
"sideBarBackground": "#181818",
"sideBarBorder": "#2b2b2b",
"statusBarBackground": "#181818",
"statusBarBorder": "#2b2b2b",
"statusBarNoFolderBackground": "#1f1f1f"
},
"layoutInfo": {
"sideBarSide": "left",
"editorPartMinWidth": 220,
"titleBarHeight": 35,
"activityBarWidth": 0,
"sideBarWidth": 300,
"statusBarHeight": 22,
"windowBorder": false
}
},
"windowsState": {
"lastActiveWindow": {
"folder": "file:///d%3A/W/python/001cursro.app/interactive",
"backupPath": "C:\\Users\\huangzhen\\AppData\\Roaming\\Cursor\\Backups\\385f155a4a13070be99ee4e76a057235",
"uiState": {
"mode": 0,
"x": 512,
"y": 192,
"width": 1024,
"height": 768
}
},
"openedWindows": []
}
},
"registry": {
"HKLM_MachineGuid": {
"exists": true,
"value": "948b93c1-ee34-4a48-95d0-a2fce9af92b1"
},
"HKCU_cursor_shell": {
"exists": false,
"values": {}
},
"HKCU_cursor_command": {
"exists": false,
"values": {}
},
"HKCU_cursor_auth": {
"exists": false,
"values": {}
},
"HKCU_cursor_updates": {
"exists": false,
"values": {}
},
"HKCU_cursor_main": {
"exists": false,
"values": {}
}
},
"files": {
"storage": {
"exists": true,
"is_dir": false,
"size": 2214,
"modified_time": "2025-02-12T12:36:27.187387"
},
"storage_backup": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:33:10.408749"
},
"user_data": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"global_storage": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:14.253083"
},
"cache": {
"exists": false,
"is_dir": null,
"size": null,
"modified_time": null
},
"updater": {
"exists": true,
"is_dir": false,
"size": 0,
"modified_time": "2025-02-10T17:19:39.071580"
}
},
"telemetry": {
"machineId": "9eb67b11924f32572a67e6480ce4f1cabf3f61503aa4918af506b259527a4745",
"macMachineId": "ff2a4a580f6e9e484c830204bb502866e9a333d3e0299ef81c34e01940da953e",
"devDeviceId": "1ae7f91c-3ab8-448c-bbd3-ef34345a5b05",
"sqmId": "{D73E6881-666C-4182-8CB2-E2A3EED5AEFF}"
}
}

View File

@@ -1,5 +1,7 @@
# -*- mode: python ; coding: utf-8 -*-
import os
import sys
from PyInstaller.utils.hooks import collect_all
def get_version():
with open('version.txt', 'r', encoding='utf-8') as f:
@@ -8,26 +10,43 @@ def get_version():
version = get_version()
# 收集所有需要的依赖
datas = [('icon', 'icon'), ('version.txt', '.')]
binaries = []
hiddenimports = [
'win32gui', 'win32con', 'win32process', 'psutil', # Windows API 相关
'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets', # GUI 相关
'PyQt5.sip', # PyQt5 必需
'PyQt5.QtNetwork', # 网络相关
'PIL', # Pillow 相关
'PIL._imaging', # Pillow 核心
'requests', 'urllib3', 'certifi', # 网络请求相关
'json', 'uuid', 'hashlib', 'logging', # 基础功能相关
'importlib', # 导入相关
'pkg_resources', # 包资源
]
# 主要的分析对象
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[('icon', 'icon'), ('version.txt', '.')],
hiddenimports=[
'win32gui', 'win32con', 'win32process', 'psutil', # Windows API 相关
'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets', # GUI 相关
'requests', 'urllib3', 'certifi', # 网络请求相关
'json', 'uuid', 'hashlib', 'logging' # 基础功能相关
],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
excludes=['_tkinter', 'tkinter', 'Tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
noarchive=False,
optimize=0,
module_collection_mode={'PyQt5': 'pyz+py'},
)
# 创建PYZ
pyz = PYZ(a.pure)
# 创建EXE
exe = EXE(
pyz,
a.scripts,

View File

@@ -1,59 +0,0 @@
{
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"after": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
}
}
},
"file_changes": {
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
}
},
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
}
},
"global_storage": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
}
}
}
}

File diff suppressed because it is too large Load Diff

BIN
icon/logo1.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
icon/logo2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
icon/logo3.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

36
main.py
View File

@@ -6,7 +6,9 @@ import atexit
import shutil
import tempfile
from pathlib import Path
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtWidgets import QApplication, QMessageBox, QSystemTrayIcon, QMenu
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from gui.main_window import MainWindow
def cleanup_temp():
@@ -50,6 +52,9 @@ def main():
# 注册退出时的清理函数
atexit.register(cleanup_temp)
# 创建QApplication实例
app = QApplication(sys.argv)
setup_logging()
# 检查Python版本
@@ -64,8 +69,32 @@ def main():
logging.info(f" - {p}")
logging.info("正在初始化主窗口...")
app = QApplication(sys.argv)
# 设置应用程序ID (在设置图标之前)
if sys.platform == "win32":
import ctypes
myappid = u'nezha.cursor.helper.v3'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
logging.info(f"设置应用程序ID: {myappid}")
# 设置应用程序图标
try:
icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icon", "two.ico")
if os.path.exists(icon_path):
app_icon = QIcon(icon_path)
if not app_icon.isNull():
app.setWindowIcon(app_icon)
logging.info(f"成功设置应用程序图标: {icon_path}")
else:
logging.error("图标文件加载失败")
else:
logging.error(f"图标文件不存在: {icon_path}")
except Exception as e:
logging.error(f"设置应用程序图标失败: {str(e)}")
window = MainWindow()
window.setWindowIcon(app.windowIcon()) # 确保窗口使用相同的图标
logging.info("正在启动主窗口...")
window.show()
@@ -75,7 +104,8 @@ def main():
error_msg = f"程序运行出错: {str(e)}\n{traceback.format_exc()}"
logging.error(error_msg)
# 使用 QMessageBox 显示错误
app = QApplication(sys.argv)
if QApplication.instance() is None:
app = QApplication(sys.argv)
QMessageBox.critical(None, "错误", error_msg)
sys.exit(1)

View File

@@ -1,4 +1,10 @@
# Use Tsinghua mirror for faster download in China:
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
requests==2.31.0
setuptools>=68.0.0
altgraph>=0.17.4
pyinstaller==6.3.0
pillow==10.2.0 # 用于处理图标
setuptools==65.5.1 # 解决pkg_resources.extern问题
pillow==10.2.0
PyQt5==5.15.10
pywin32==306

View File

@@ -1,106 +0,0 @@
{
"github_changes": {
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "d890ab3d-43cd-40c8-a9ef-f5683b5a64e3"
},
"after": {
"exists": true,
"value": "776c6b6c-195f-42dc-94d6-72b70c3aca74"
}
}
},
"file_changes": {
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 3427,
"modified_time": "2025-02-12T11:40:57.046415"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1891,
"modified_time": "2025-02-12T11:48:42.627574"
}
},
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:00:01.555876"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:26.403770"
}
},
"global_storage": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:47:27.627883"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T11:48:47.490659"
}
}
}
},
"our_changes": {
"package_json_changes": {},
"registry_changes": {
"HKLM_MachineGuid": {
"before": {
"exists": true,
"value": "948b93c1-ee34-4a48-95d0-a2fce9af92b1"
},
"after": {
"exists": true,
"value": "1deb25e7-cdd4-4367-a347-fba8b33b9b03"
}
}
},
"file_changes": {
"storage_backup": {
"before": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:33:10.408749"
},
"after": {
"exists": true,
"is_dir": true,
"size": null,
"modified_time": "2025-02-12T12:37:17.371311"
}
},
"storage": {
"before": {
"exists": true,
"is_dir": false,
"size": 2214,
"modified_time": "2025-02-12T12:36:27.187387"
},
"after": {
"exists": true,
"is_dir": false,
"size": 1980,
"modified_time": "2025-02-12T12:37:17.428609"
}
}
}
}
}

View File

@@ -4,8 +4,15 @@ import logging
from pathlib import Path
class Config:
"""配置类"""
def __init__(self):
self.api_base_url = "https://cursorapi.nosqli.com/admin"
self.base_url = "https://cursorapi.nosqli.com"
self.api_endpoints = {
"activate": f"{self.base_url}/admin/api.member/activate",
"status": f"{self.base_url}/admin/api.member/status",
"get_unused": f"{self.base_url}/admin/api.account/getUnused"
}
self.config_dir = Path(os.path.expanduser("~")) / ".cursor_switcher"
self.config_file = self.config_dir / "config.json"
self.member_file = self.config_dir / "member.json"
@@ -64,4 +71,15 @@ class Config:
}
with open(self.config_file, "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
self.api_token = api_token
self.api_token = api_token
def get_api_url(self, endpoint_name: str) -> str:
"""获取API端点URL
Args:
endpoint_name: 端点名称
Returns:
str: 完整的API URL
"""
return self.api_endpoints.get(endpoint_name, "")

View File

@@ -1 +1 @@
3.2.8
3.3.9