Browse Source

chore(scripts): 删除 Cursor 免费试用重置脚本

- 移除了 macOS 平台下用于重置 Cursor 编辑器免费试用期的 shell 脚本
- 该脚本包含修改应用程序文件、重置配置及权限修复等功能
- 脚本文件路径为 scripts/run/cursor_mac_free_trial_reset.sh
- 此变更不影响其他平台或功能的正常使用
煎饼果子卷鲨鱼辣椒 1 month ago
parent
commit
139ba0b638
  1. 1401
      scripts/run/cursor_mac_free_trial_reset.sh
  2. 688
      scripts/run/cursor_mac_id_modifier_new.sh
  3. 607
      scripts/run/cursor_win_id_modifier_old.ps1

1401
scripts/run/cursor_mac_free_trial_reset.sh
File diff suppressed because it is too large
View File

688
scripts/run/cursor_mac_id_modifier_new.sh

@ -1,688 +0,0 @@
#!/bin/bash
# ========================================
# Cursor macOS 机器码修改脚本 (重构精简版)
# ========================================
#
# 🎯 重构目标:
# - 简化脚本复杂度,从3158行压缩到约900行
# - 自动化权限修复,解决EACCES权限错误
# - 减少用户交互步骤,提升执行效率
# - 保持所有原有功能完整性
#
# 🚀 执行流程说明:
# 1. 环境检测和权限预修复
# 2. 用户选择执行模式(仅修改 vs 完整重置)
# 3. 自动执行所有必要步骤
# 4. 智能设备识别绕过(MAC地址或JS内核修改)
# 5. 自动权限修复和验证
#
# ========================================
set -e
# ==================== 核心配置 ====================
LOG_FILE="/tmp/cursor_reset_$(date +%Y%m%d_%H%M%S).log"
CURSOR_APP_PATH="/Applications/Cursor.app"
STORAGE_FILE="$HOME/Library/Application Support/Cursor/User/globalStorage/storage.json"
BACKUP_DIR="$HOME/Library/Application Support/Cursor/User/globalStorage/backups"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# ==================== 统一工具函数 ====================
# 初始化日志
init_log() {
echo "========== Cursor重构脚本执行日志 $(date) ==========" > "$LOG_FILE"
chmod 644 "$LOG_FILE"
}
# 精简日志函数
log() {
local level="$1"
local msg="$2"
local color=""
case "$level" in
"INFO") color="$GREEN" ;;
"WARN") color="$YELLOW" ;;
"ERROR") color="$RED" ;;
*) color="$BLUE" ;;
esac
echo -e "${color}[$level]${NC} $msg"
echo "[$level] $(date '+%H:%M:%S') $msg" >> "$LOG_FILE"
}
# 统一权限管理器 - 解决所有权限问题
fix_permissions() {
log "INFO" "🔧 执行统一权限修复..."
local cursor_support="$HOME/Library/Application Support/Cursor"
local cursor_home="$HOME/.cursor"
# 创建必要目录结构
local dirs=(
"$cursor_support"
"$cursor_support/User"
"$cursor_support/User/globalStorage"
"$cursor_support/logs"
"$cursor_support/CachedData"
"$cursor_home"
"$cursor_home/extensions"
)
for dir in "${dirs[@]}"; do
mkdir -p "$dir" 2>/dev/null || true
done
# 执行核心权限修复命令
if sudo chown -R "$(whoami)" "$cursor_support" 2>/dev/null && \
sudo chown -R "$(whoami)" "$cursor_home" 2>/dev/null && \
chmod -R u+w "$cursor_support" 2>/dev/null && \
chmod -R u+w "$cursor_home/extensions" 2>/dev/null; then
log "INFO" "✅ 权限修复成功"
return 0
else
log "ERROR" "❌ 权限修复失败"
return 1
fi
}
# 环境检测器
detect_environment() {
log "INFO" "🔍 检测系统环境..."
# 检测macOS版本和硬件
MACOS_VERSION=$(sw_vers -productVersion)
HARDWARE_TYPE=$(uname -m)
if [[ "$HARDWARE_TYPE" == "arm64" ]]; then
HARDWARE_TYPE="Apple Silicon"
else
HARDWARE_TYPE="Intel"
fi
# 检测兼容性
local macos_major=$(echo "$MACOS_VERSION" | cut -d. -f1)
if [[ $macos_major -ge 14 ]] || [[ "$HARDWARE_TYPE" == "Apple Silicon" ]]; then
MAC_COMPATIBLE=false
log "WARN" "⚠️ 检测到MAC地址修改受限环境: macOS $MACOS_VERSION ($HARDWARE_TYPE)"
else
MAC_COMPATIBLE=true
log "INFO" "✅ 环境兼容性检查通过"
fi
# 检查Python3
if ! command -v python3 >/dev/null 2>&1; then
log "ERROR" "❌ 未找到Python3,请安装: brew install python3"
return 1
fi
# 检查Cursor应用
if [ ! -d "$CURSOR_APP_PATH" ]; then
log "ERROR" "❌ 未找到Cursor应用: $CURSOR_APP_PATH"
return 1
fi
log "INFO" "✅ 环境检测完成: macOS $MACOS_VERSION ($HARDWARE_TYPE)"
return 0
}
# 进程管理器
manage_cursor_process() {
local action="$1" # kill 或 start
case "$action" in
"kill")
log "INFO" "🔄 关闭Cursor进程..."
pkill -f "Cursor" 2>/dev/null || true
sleep 2
# 验证是否关闭
if pgrep -f "Cursor" >/dev/null; then
pkill -9 -f "Cursor" 2>/dev/null || true
sleep 2
fi
log "INFO" "✅ Cursor进程已关闭"
;;
"start")
log "INFO" "🚀 启动Cursor..."
"$CURSOR_APP_PATH/Contents/MacOS/Cursor" > /dev/null 2>&1 &
sleep 15
log "INFO" "✅ Cursor已启动"
;;
esac
}
# 错误处理器
handle_error() {
local error_msg="$1"
local recovery_action="$2"
log "ERROR" "❌ 错误: $error_msg"
if [ -n "$recovery_action" ]; then
log "INFO" "🔄 尝试恢复: $recovery_action"
eval "$recovery_action"
fi
log "INFO" "💡 如需帮助,请查看日志: $LOG_FILE"
}
# ==================== 功能模块 ====================
# 机器码修改器
modify_machine_code() {
log "INFO" "🛠️ 开始修改机器码配置..."
# 检查配置文件
if [ ! -f "$STORAGE_FILE" ]; then
log "ERROR" "❌ 配置文件不存在,请先启动Cursor生成配置"
return 1
fi
# 创建备份
mkdir -p "$BACKUP_DIR"
local backup_file="$BACKUP_DIR/storage.json.backup_$(date +%Y%m%d_%H%M%S)"
cp "$STORAGE_FILE" "$backup_file" || {
log "ERROR" "❌ 备份失败"
return 1
}
# 生成新ID
local machine_id="auth0|user_$(openssl rand -hex 16)"
local mac_machine_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
local device_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
local sqm_id="{$(uuidgen | tr '[:lower:]' '[:upper:]')}"
# 修改配置文件
local python_result=$(python3 -c "
import json
import sys
try:
with open('$STORAGE_FILE', 'r', encoding='utf-8') as f:
config = json.load(f)
config['telemetry.machineId'] = '$machine_id'
config['telemetry.macMachineId'] = '$mac_machine_id'
config['telemetry.devDeviceId'] = '$device_id'
config['telemetry.sqmId'] = '$sqm_id'
with open('$STORAGE_FILE', 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print('SUCCESS')
except Exception as e:
print(f'ERROR: {e}')
sys.exit(1)
" 2>&1)
if echo "$python_result" | grep -q "SUCCESS"; then
# 设置只读保护
chmod 444 "$STORAGE_FILE" 2>/dev/null || true
log "INFO" "✅ 机器码修改成功"
log "INFO" "💾 备份保存至: $(basename "$backup_file")"
return 0
else
log "ERROR" "❌ 机器码修改失败: $python_result"
cp "$backup_file" "$STORAGE_FILE" 2>/dev/null || true
return 1
fi
}
# 智能设备绕过器 - 根据环境自动选择最佳方案
bypass_device_detection() {
log "INFO" "🔧 开始智能设备识别绕过..."
# 根据环境兼容性选择方案
if [ "$MAC_COMPATIBLE" = false ]; then
log "INFO" "💡 检测到MAC地址修改受限,使用JS内核修改方案"
return modify_js_kernel
else
log "INFO" "💡 尝试MAC地址修改方案"
if modify_mac_address; then
return 0
else
log "WARN" "⚠️ MAC地址修改失败,切换到JS内核修改"
return modify_js_kernel
fi
fi
}
# MAC地址修改器(简化版)
modify_mac_address() {
log "INFO" "🌐 开始MAC地址修改..."
# 获取活动网络接口
local interfaces=()
while IFS= read -r line; do
if [[ $line == "Hardware Port: Wi-Fi" || $line == "Hardware Port: Ethernet" ]]; then
read -r dev_line
local device=$(echo "$dev_line" | awk '{print $2}')
if [ -n "$device" ] && ifconfig "$device" 2>/dev/null | grep -q "status: active"; then
interfaces+=("$device")
fi
fi
done < <(networksetup -listallhardwareports)
if [ ${#interfaces[@]} -eq 0 ]; then
log "WARN" "⚠️ 未找到活动网络接口"
return 1
fi
local success_count=0
for interface in "${interfaces[@]}"; do
log "INFO" "🔧 处理接口: $interface"
# 生成新MAC地址
local new_mac=$(printf '%02x:%02x:%02x:%02x:%02x:%02x' \
$(( (RANDOM & 0xFC) | 0x02 )) $((RANDOM%256)) $((RANDOM%256)) \
$((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
# 尝试修改MAC地址
if sudo ifconfig "$interface" down 2>/dev/null && \
sleep 2 && \
sudo ifconfig "$interface" ether "$new_mac" 2>/dev/null && \
sudo ifconfig "$interface" up 2>/dev/null; then
log "INFO" "✅ 接口 $interface MAC地址修改成功: $new_mac"
((success_count++))
else
log "WARN" "⚠️ 接口 $interface MAC地址修改失败"
fi
sleep 2
done
if [ $success_count -gt 0 ]; then
log "INFO" "✅ MAC地址修改完成 ($success_count/${#interfaces[@]} 成功)"
return 0
else
return 1
fi
}
# JS内核修改器(简化版)
modify_js_kernel() {
log "INFO" "🔧 开始JS内核修改..."
# 关闭Cursor
manage_cursor_process "kill"
# 目标JS文件
local js_files=(
"$CURSOR_APP_PATH/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js"
"$CURSOR_APP_PATH/Contents/Resources/app/out/main.js"
)
# 检查是否需要修改
local need_modify=false
for file in "${js_files[@]}"; do
if [ -f "$file" ] && ! grep -q "return crypto.randomUUID()" "$file" 2>/dev/null; then
need_modify=true
break
fi
done
if [ "$need_modify" = false ]; then
log "INFO" "✅ JS文件已修改,跳过"
return 0
fi
# 创建备份
local backup_app="/tmp/Cursor.app.backup_$(date +%Y%m%d_%H%M%S)"
cp -R "$CURSOR_APP_PATH" "$backup_app" || {
log "ERROR" "❌ 创建备份失败"
return 1
fi
# 生成设备ID
local new_uuid=$(uuidgen | tr '[:upper:]' '[:lower:]')
local machine_id="auth0|user_$(openssl rand -hex 16)"
# 修改JS文件
local modified_count=0
for file in "${js_files[@]}"; do
if [ ! -f "$file" ]; then
continue
fi
log "INFO" "📝 处理文件: $(basename "$file")"
# 创建注入代码
local inject_code="
// Cursor设备标识符劫持 - $(date +%Y%m%d%H%M%S)
import crypto from 'crypto';
const originalRandomUUID = crypto.randomUUID;
crypto.randomUUID = function() { return '$new_uuid'; };
globalThis.getMachineId = function() { return '$machine_id'; };
console.log('Cursor设备标识符已劫持');
"
# 注入代码
echo "$inject_code" > "${file}.new"
cat "$file" >> "${file}.new"
mv "${file}.new" "$file"
((modified_count++))
log "INFO" "✅ 文件修改成功: $(basename "$file")"
done
if [ $modified_count -gt 0 ]; then
# 重新签名
if codesign --sign - --force --deep "$CURSOR_APP_PATH" 2>/dev/null; then
log "INFO" "✅ JS内核修改完成 ($modified_count 个文件)"
return 0
else
log "WARN" "⚠️ 签名失败,但修改已完成"
return 0
fi
else
log "ERROR" "❌ 未修改任何文件"
return 1
fi
}
# 环境重置器
reset_environment() {
log "INFO" "🗑️ 开始环境重置..."
# 关闭Cursor
manage_cursor_process "kill"
# 删除目标文件夹
local folders=(
"$HOME/Library/Application Support/Cursor"
"$HOME/.cursor"
)
local deleted_count=0
for folder in "${folders[@]}"; do
if [ -d "$folder" ]; then
if rm -rf "$folder"; then
log "INFO" "✅ 已删除: $folder"
((deleted_count++))
else
log "ERROR" "❌ 删除失败: $folder"
fi
fi
done
# 修复权限
fix_permissions
log "INFO" "✅ 环境重置完成 (删除 $deleted_count 个文件夹)"
return 0
}
# 禁用自动更新
disable_auto_update() {
log "INFO" "🚫 禁用自动更新..."
local app_update_yml="$CURSOR_APP_PATH/Contents/Resources/app-update.yml"
local updater_path="$HOME/Library/Application Support/Caches/cursor-updater"
# 禁用app-update.yml
if [ -f "$app_update_yml" ]; then
sudo cp "$app_update_yml" "${app_update_yml}.bak" 2>/dev/null || true
sudo bash -c "echo '' > \"$app_update_yml\"" 2>/dev/null || true
sudo chmod 444 "$app_update_yml" 2>/dev/null || true
fi
# 禁用cursor-updater
sudo rm -rf "$updater_path" 2>/dev/null || true
sudo touch "$updater_path" 2>/dev/null || true
sudo chmod 444 "$updater_path" 2>/dev/null || true
log "INFO" "✅ 自动更新已禁用"
}
# 修复应用签名问题
fix_app_signature() {
log "INFO" "🔧 修复应用签名..."
# 移除隔离属性
sudo find "$CURSOR_APP_PATH" -print0 2>/dev/null | \
xargs -0 sudo xattr -d com.apple.quarantine 2>/dev/null || true
# 重新签名
sudo codesign --force --deep --sign - "$CURSOR_APP_PATH" 2>/dev/null || true
log "INFO" "✅ 应用签名修复完成"
}
# ==================== 主执行流程 ====================
# 快速模式 - 仅修改机器码
quick_mode() {
log "INFO" "🚀 执行快速模式(仅修改机器码)..."
# 检查环境
if ! detect_environment; then
handle_error "环境检测失败" "exit 1"
return 1
fi
# 预修复权限
fix_permissions
# 修改机器码
if ! modify_machine_code; then
handle_error "机器码修改失败" "exit 1"
return 1
fi
# 设备绕过
bypass_device_detection || log "WARN" "⚠️ 设备绕过失败,但机器码修改已完成"
# 禁用更新
disable_auto_update
# 修复签名
fix_app_signature
# 最终权限修复
fix_permissions
log "INFO" "🎉 快速模式执行完成!"
return 0
}
# 完整模式 - 重置环境+修改机器码
full_mode() {
log "INFO" "🚀 执行完整模式(重置环境+修改机器码)..."
# 检查环境
if ! detect_environment; then
handle_error "环境检测失败" "exit 1"
return 1
fi
# 环境重置
if ! reset_environment; then
handle_error "环境重置失败" "exit 1"
return 1
fi
# 启动Cursor生成配置
manage_cursor_process "start"
# 等待配置文件生成
local config_wait=0
while [ ! -f "$STORAGE_FILE" ] && [ $config_wait -lt 30 ]; do
sleep 2
((config_wait += 2))
log "INFO" "⏳ 等待配置文件生成... ($config_wait/30秒)"
done
# 关闭Cursor
manage_cursor_process "kill"
# 修改机器码
if ! modify_machine_code; then
handle_error "机器码修改失败" "exit 1"
return 1
fi
# 设备绕过
bypass_device_detection || log "WARN" "⚠️ 设备绕过失败,但机器码修改已完成"
# 禁用更新
disable_auto_update
# 修复签名
fix_app_signature
# 最终权限修复
fix_permissions
log "INFO" "🎉 完整模式执行完成!"
return 0
}
# ==================== 用户界面 ====================
# 显示Logo和信息
show_header() {
clear
echo -e "
██████╗██╗ ██╗██████╗ ███████╗ ██████╗ ██████╗
██╔════╝██║ ██║██╔══██╗██╔════╝██╔═══██╗██╔══██╗
██║ ██║ ██║██████╔╝███████╗██║ ██║██████╔╝
██║ ██║ ██║██╔══██╗╚════██║██║ ██║██╔══██╗
╚██████╗╚██████╔╝██║ ██║███████║╚██████╔╝██║ ██║
╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝
"
echo -e "${BLUE}================================${NC}"
echo -e "${GREEN}🚀 Cursor 机器码修改工具 (重构版) ${NC}"
echo -e "${YELLOW}📱 关注公众号【煎饼果子卷AI】 ${NC}"
echo -e "${BLUE}================================${NC}"
echo
echo -e "${YELLOW}💡 [免费工具]${NC} 如果对您有帮助,请关注公众号支持开发者"
echo
}
# 用户选择菜单
user_menu() {
echo -e "${GREEN}🎯 [选择模式]${NC} 请选择执行模式:"
echo
echo -e "${BLUE} 1️⃣ 快速模式 - 仅修改机器码${NC}"
echo -e "${YELLOW} • 保留现有配置和数据${NC}"
echo -e "${YELLOW} • 执行时间约30秒${NC}"
echo -e "${YELLOW} • 自动权限修复${NC}"
echo
echo -e "${BLUE} 2️⃣ 完整模式 - 重置环境+修改机器码${NC}"
echo -e "${RED} • 删除所有Cursor配置(请备份)${NC}"
echo -e "${YELLOW} • 执行时间约90秒${NC}"
echo -e "${YELLOW} • 彻底重置试用状态${NC}"
echo
while true; do
read -p "请输入选择 (1 或 2): " choice
case "$choice" in
1)
log "INFO" "✅ 用户选择:快速模式"
return 1
;;
2)
echo -e "${RED}⚠️ [警告]${NC} 完整模式将删除所有Cursor配置!"
read -p "确认执行?(输入 yes 确认): " confirm
if [ "$confirm" = "yes" ]; then
log "INFO" "✅ 用户选择:完整模式"
return 2
else
echo -e "${YELLOW}👋 [取消]${NC} 请重新选择"
continue
fi
;;
*)
echo -e "${RED}❌ [错误]${NC} 无效选择,请输入 1 或 2"
;;
esac
done
}
# 显示完成信息
show_completion() {
echo
echo -e "${GREEN}================================${NC}"
echo -e "${BLUE} 🎯 执行完成总结 ${NC}"
echo -e "${GREEN}================================${NC}"
echo -e "${GREEN}✅ 机器码配置: 已修改${NC}"
echo -e "${GREEN}✅ 设备识别绕过: 已完成${NC}"
echo -e "${GREEN}✅ 自动更新: 已禁用${NC}"
echo -e "${GREEN}✅ 权限修复: 已完成${NC}"
echo -e "${GREEN}✅ 应用签名: 已修复${NC}"
echo -e "${GREEN}================================${NC}"
echo
echo -e "${YELLOW}📱 关注公众号【煎饼果子卷AI】获取更多Cursor技巧${NC}"
echo
echo -e "${BLUE}🚀 [下一步]${NC} 现在可以启动Cursor使用了!"
echo -e "${BLUE}📄 [日志]${NC} 详细日志保存在: $LOG_FILE"
echo
}
# ==================== 主函数 ====================
main() {
# 检查权限
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}❌ [错误]${NC} 请使用 sudo 运行此脚本"
echo "示例: sudo $0"
exit 1
fi
# 检查macOS
if [[ $(uname) != "Darwin" ]]; then
echo -e "${RED}❌ [错误]${NC} 本脚本仅支持 macOS 系统"
exit 1
fi
# 初始化
init_log
log "INFO" "🚀 Cursor重构脚本启动..."
# 预修复权限
fix_permissions
# 显示界面
show_header
# 用户选择
user_menu
local mode=$?
echo
log "INFO" "🚀 开始执行,请稍候..."
echo
# 执行对应模式
case $mode in
1)
if quick_mode; then
show_completion
exit 0
else
log "ERROR" "❌ 快速模式执行失败"
exit 1
fi
;;
2)
if full_mode; then
show_completion
exit 0
else
log "ERROR" "❌ 完整模式执行失败"
exit 1
fi
;;
esac
}
# 执行主函数
main "$@"

607
scripts/run/cursor_win_id_modifier_old.ps1

@ -1,607 +0,0 @@
# 设置输出编码为 UTF-8
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# 颜色定义
$RED = "`e[31m"
$GREEN = "`e[32m"
$YELLOW = "`e[33m"
$BLUE = "`e[34m"
$NC = "`e[0m"
# 配置文件路径
$STORAGE_FILE = "$env:APPDATA\Cursor\User\globalStorage\storage.json"
$BACKUP_DIR = "$env:APPDATA\Cursor\User\globalStorage\backups"
# 新增 Cursor 初始化函数
function Cursor-初始化 {
Write-Host "$GREEN[信息]$NC 正在执行 Cursor 初始化清理..."
$BASE_PATH = "$env:APPDATA\Cursor\User"
$filesToDelete = @(
(Join-Path -Path $BASE_PATH -ChildPath "globalStorage\\state.vscdb"),
(Join-Path -Path $BASE_PATH -ChildPath "globalStorage\\state.vscdb.backup")
)
$folderToCleanContents = Join-Path -Path $BASE_PATH -ChildPath "History"
$folderToDeleteCompletely = Join-Path -Path $BASE_PATH -ChildPath "workspaceStorage"
Write-Host "$BLUE[调试]$NC 基础路径: $BASE_PATH"
# 删除指定文件
foreach ($file in $filesToDelete) {
Write-Host "$BLUE[调试]$NC 检查文件: $file"
if (Test-Path $file) {
try {
Remove-Item -Path $file -Force -ErrorAction Stop
Write-Host "$GREEN[成功]$NC 已删除文件: $file"
}
catch {
Write-Host "$RED[错误]$NC 删除文件 $file 失败: $($_.Exception.Message)"
}
} else {
Write-Host "$YELLOW[警告]$NC 文件不存在,跳过删除: $file"
}
}
# 清空指定文件夹内容
Write-Host "$BLUE[调试]$NC 检查待清空文件夹: $folderToCleanContents"
if (Test-Path $folderToCleanContents) {
try {
# 获取子项进行删除,以避免删除 History 文件夹本身
Get-ChildItem -Path $folderToCleanContents -Recurse | Remove-Item -Recurse -Force -ErrorAction Stop
Write-Host "$GREEN[成功]$NC 已清空文件夹内容: $folderToCleanContents"
}
catch {
Write-Host "$RED[错误]$NC 清空文件夹 $folderToCleanContents 内容失败: $($_.Exception.Message)"
}
} else {
Write-Host "$YELLOW[警告]$NC 文件夹不存在,跳过清空: $folderToCleanContents"
}
# 删除指定文件夹及其内容
Write-Host "$BLUE[调试]$NC 检查待删除文件夹: $folderToDeleteCompletely"
if (Test-Path $folderToDeleteCompletely) {
try {
Remove-Item -Path $folderToDeleteCompletely -Recurse -Force -ErrorAction Stop
Write-Host "$GREEN[成功]$NC 已删除文件夹: $folderToDeleteCompletely"
}
catch {
Write-Host "$RED[错误]$NC 删除文件夹 $folderToDeleteCompletely 失败: $($_.Exception.Message)"
}
} else {
Write-Host "$YELLOW[警告]$NC 文件夹不存在,跳过删除: $folderToDeleteCompletely"
}
Write-Host "$GREEN[信息]$NC Cursor 初始化清理完成。"
Write-Host "" # 添加空行以改善输出格式
}
# 检查管理员权限
function Test-Administrator {
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($user)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
if (-not (Test-Administrator)) {
Write-Host "$RED[错误]$NC 请以管理员身份运行此脚本"
Write-Host "请右键点击脚本,选择'以管理员身份运行'"
Read-Host "按回车键退出"
exit 1
}
# 显示 Logo
Clear-Host
Write-Host @"
"@
Write-Host "$BLUE================================$NC"
Write-Host "$GREEN Cursor 设备ID 修改工具 $NC"
Write-Host "$YELLOW 关注公众号【煎饼果子卷AI】 $NC"
Write-Host "$YELLOW 一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬) $NC"
Write-Host "$YELLOW [重要提示] 本工具免费,如果对您有帮助,请关注公众号【煎饼果子卷AI】 $NC"
Write-Host ""
Write-Host "$YELLOW⚡ [小小广告] Cursor官网正规成品号:Pro¥65 | Pro+¥265 | Ultra¥888 独享账号/7天质保,WeChat:JavaRookie666 $NC"
Write-Host "$BLUE================================$NC"
# 获取并显示 Cursor 版本
function Get-CursorVersion {
try {
# 主要检测路径
$packagePath = "$env:LOCALAPPDATA\\Programs\\cursor\\resources\\app\\package.json"
if (Test-Path $packagePath) {
$packageJson = Get-Content $packagePath -Raw | ConvertFrom-Json
if ($packageJson.version) {
Write-Host "$GREEN[信息]$NC 当前安装的 Cursor 版本: v$($packageJson.version)"
return $packageJson.version
}
}
# 备用路径检测
$altPath = "$env:LOCALAPPDATA\\cursor\\resources\\app\\package.json"
if (Test-Path $altPath) {
$packageJson = Get-Content $altPath -Raw | ConvertFrom-Json
if ($packageJson.version) {
Write-Host "$GREEN[信息]$NC 当前安装的 Cursor 版本: v$($packageJson.version)"
return $packageJson.version
}
}
Write-Host "$YELLOW[警告]$NC 无法检测到 Cursor 版本"
Write-Host "$YELLOW[提示]$NC 请确保 Cursor 已正确安装"
return $null
}
catch {
Write-Host "$RED[错误]$NC 获取 Cursor 版本失败: $_"
return $null
}
}
# 获取并显示版本信息
$cursorVersion = Get-CursorVersion
Write-Host ""
Write-Host "$YELLOW[重要提示]$NC 最新的 1.0.x (以支持)"
Write-Host ""
# 检查并关闭 Cursor 进程
Write-Host "$GREEN[信息]$NC 检查 Cursor 进程..."
function Get-ProcessDetails {
param($processName)
Write-Host "$BLUE[调试]$NC 正在获取 $processName 进程详细信息:"
Get-WmiObject Win32_Process -Filter "name='$processName'" |
Select-Object ProcessId, ExecutablePath, CommandLine |
Format-List
}
# 定义最大重试次数和等待时间
$MAX_RETRIES = 5
$WAIT_TIME = 1
# 处理进程关闭
function Close-CursorProcess {
param($processName)
$process = Get-Process -Name $processName -ErrorAction SilentlyContinue
if ($process) {
Write-Host "$YELLOW[警告]$NC 发现 $processName 正在运行"
Get-ProcessDetails $processName
Write-Host "$YELLOW[警告]$NC 尝试关闭 $processName..."
Stop-Process -Name $processName -Force
$retryCount = 0
while ($retryCount -lt $MAX_RETRIES) {
$process = Get-Process -Name $processName -ErrorAction SilentlyContinue
if (-not $process) { break }
$retryCount++
if ($retryCount -ge $MAX_RETRIES) {
Write-Host "$RED[错误]$NC 在 $MAX_RETRIES 次尝试后仍无法关闭 $processName"
Get-ProcessDetails $processName
Write-Host "$RED[错误]$NC 请手动关闭进程后重试"
Read-Host "按回车键退出"
exit 1
}
Write-Host "$YELLOW[警告]$NC 等待进程关闭,尝试 $retryCount/$MAX_RETRIES..."
Start-Sleep -Seconds $WAIT_TIME
}
Write-Host "$GREEN[信息]$NC $processName 已成功关闭"
}
}
# 关闭所有 Cursor 进程
Close-CursorProcess "Cursor"
Close-CursorProcess "cursor"
# 执行 Cursor 初始化清理
# Cursor-初始化
# 创建备份目录
if (-not (Test-Path $BACKUP_DIR)) {
New-Item -ItemType Directory -Path $BACKUP_DIR | Out-Null
}
# 备份现有配置
if (Test-Path $STORAGE_FILE) {
Write-Host "$GREEN[信息]$NC 正在备份配置文件..."
$backupName = "storage.json.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
Copy-Item $STORAGE_FILE "$BACKUP_DIR\$backupName"
}
# 生成新的 ID
Write-Host "$GREEN[信息]$NC 正在生成新的 ID..."
# 在颜色定义后添加此函数
function Get-RandomHex {
param (
[int]$length
)
$bytes = New-Object byte[] ($length)
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
$rng.GetBytes($bytes)
$hexString = [System.BitConverter]::ToString($bytes) -replace '-',''
$rng.Dispose()
return $hexString
}
# 改进 ID 生成函数
function New-StandardMachineId {
$template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
$result = $template -replace '[xy]', {
param($match)
$r = [Random]::new().Next(16)
$v = if ($match.Value -eq "x") { $r } else { ($r -band 0x3) -bor 0x8 }
return $v.ToString("x")
}
return $result
}
# 在生成 ID 时使用新函数
$MAC_MACHINE_ID = New-StandardMachineId
$UUID = [System.Guid]::NewGuid().ToString()
# 将 auth0|user_ 转换为字节数组的十六进制
$prefixBytes = [System.Text.Encoding]::UTF8.GetBytes("auth0|user_")
$prefixHex = -join ($prefixBytes | ForEach-Object { '{0:x2}' -f $_ })
# 生成32字节(64个十六进制字符)的随机数作为 machineId 的随机部分
$randomPart = Get-RandomHex -length 32
$MACHINE_ID = "$prefixHex$randomPart"
$SQM_ID = "{$([System.Guid]::NewGuid().ToString().ToUpper())}"
# 在Update-MachineGuid函数前添加权限检查
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "$RED[错误]$NC 请使用管理员权限运行此脚本"
Start-Process powershell "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
exit
}
function Update-MachineGuid {
try {
# 检查注册表路径是否存在,不存在则创建
$registryPath = "HKLM:\SOFTWARE\Microsoft\Cryptography"
if (-not (Test-Path $registryPath)) {
Write-Host "$YELLOW[警告]$NC 注册表路径不存在: $registryPath,正在创建..."
New-Item -Path $registryPath -Force | Out-Null
Write-Host "$GREEN[信息]$NC 注册表路径创建成功"
}
# 获取当前的 MachineGuid,如果不存在则使用空字符串作为默认值
$originalGuid = ""
try {
$currentGuid = Get-ItemProperty -Path $registryPath -Name MachineGuid -ErrorAction SilentlyContinue
if ($currentGuid) {
$originalGuid = $currentGuid.MachineGuid
Write-Host "$GREEN[信息]$NC 当前注册表值:"
Write-Host "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography"
Write-Host " MachineGuid REG_SZ $originalGuid"
} else {
Write-Host "$YELLOW[警告]$NC MachineGuid 值不存在,将创建新值"
}
} catch {
Write-Host "$YELLOW[警告]$NC 获取 MachineGuid 失败: $($_.Exception.Message)"
}
# 创建备份目录(如果不存在)
if (-not (Test-Path $BACKUP_DIR)) {
New-Item -ItemType Directory -Path $BACKUP_DIR -Force | Out-Null
}
# 创建备份文件(仅当原始值存在时)
if ($originalGuid) {
$backupFile = "$BACKUP_DIR\MachineGuid_$(Get-Date -Format 'yyyyMMdd_HHmmss').reg"
$backupResult = Start-Process "reg.exe" -ArgumentList "export", "`"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography`"", "`"$backupFile`"" -NoNewWindow -Wait -PassThru
if ($backupResult.ExitCode -eq 0) {
Write-Host "$GREEN[信息]$NC 注册表项已备份到:$backupFile"
} else {
Write-Host "$YELLOW[警告]$NC 备份创建失败,继续执行..."
}
}
# 生成新GUID
$newGuid = [System.Guid]::NewGuid().ToString()
# 更新或创建注册表值
Set-ItemProperty -Path $registryPath -Name MachineGuid -Value $newGuid -Force -ErrorAction Stop
# 验证更新
$verifyGuid = (Get-ItemProperty -Path $registryPath -Name MachineGuid -ErrorAction Stop).MachineGuid
if ($verifyGuid -ne $newGuid) {
throw "注册表验证失败:更新后的值 ($verifyGuid) 与预期值 ($newGuid) 不匹配"
}
Write-Host "$GREEN[信息]$NC 注册表更新成功:"
Write-Host "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography"
Write-Host " MachineGuid REG_SZ $newGuid"
return $true
}
catch {
Write-Host "$RED[错误]$NC 注册表操作失败:$($_.Exception.Message)"
# 尝试恢复备份(如果存在)
if (($backupFile -ne $null) -and (Test-Path $backupFile)) {
Write-Host "$YELLOW[恢复]$NC 正在从备份恢复..."
$restoreResult = Start-Process "reg.exe" -ArgumentList "import", "`"$backupFile`"" -NoNewWindow -Wait -PassThru
if ($restoreResult.ExitCode -eq 0) {
Write-Host "$GREEN[恢复成功]$NC 已还原原始注册表值"
} else {
Write-Host "$RED[错误]$NC 恢复失败,请手动导入备份文件:$backupFile"
}
} else {
Write-Host "$YELLOW[警告]$NC 未找到备份文件或备份创建失败,无法自动恢复"
}
return $false
}
}
# 创建或更新配置文件
Write-Host "$GREEN[信息]$NC 正在更新配置..."
try {
# 检查配置文件是否存在
if (-not (Test-Path $STORAGE_FILE)) {
Write-Host "$RED[错误]$NC 未找到配置文件: $STORAGE_FILE"
Write-Host "$YELLOW[提示]$NC 请先安装并运行一次 Cursor 后再使用此脚本"
Read-Host "按回车键退出"
exit 1
}
# 读取现有配置文件
try {
$originalContent = Get-Content $STORAGE_FILE -Raw -Encoding UTF8
# 将 JSON 字符串转换为 PowerShell 对象
$config = $originalContent | ConvertFrom-Json
# 备份当前值
$oldValues = @{
'machineId' = $config.'telemetry.machineId'
'macMachineId' = $config.'telemetry.macMachineId'
'devDeviceId' = $config.'telemetry.devDeviceId'
'sqmId' = $config.'telemetry.sqmId'
}
# 更新特定的值
$config.'telemetry.machineId' = $MACHINE_ID
$config.'telemetry.macMachineId' = $MAC_MACHINE_ID
$config.'telemetry.devDeviceId' = $UUID
$config.'telemetry.sqmId' = $SQM_ID
# 将更新后的对象转换回 JSON 并保存
$updatedJson = $config | ConvertTo-Json -Depth 10
[System.IO.File]::WriteAllText(
[System.IO.Path]::GetFullPath($STORAGE_FILE),
$updatedJson,
[System.Text.Encoding]::UTF8
)
Write-Host "$GREEN[信息]$NC 成功更新配置文件"
} catch {
# 如果出错,尝试恢复原始内容
if ($originalContent) {
[System.IO.File]::WriteAllText(
[System.IO.Path]::GetFullPath($STORAGE_FILE),
$originalContent,
[System.Text.Encoding]::UTF8
)
}
throw "处理 JSON 失败: $_"
}
# 直接执行更新 MachineGuid,不再询问
Update-MachineGuid
# 显示结果
Write-Host ""
Write-Host "$GREEN[信息]$NC 已更新配置:"
Write-Host "$BLUE[调试]$NC machineId: $MACHINE_ID"
Write-Host "$BLUE[调试]$NC macMachineId: $MAC_MACHINE_ID"
Write-Host "$BLUE[调试]$NC devDeviceId: $UUID"
Write-Host "$BLUE[调试]$NC sqmId: $SQM_ID"
# 显示文件树结构
Write-Host ""
Write-Host "$GREEN[信息]$NC 文件结构:"
Write-Host "$BLUE$env:APPDATA\Cursor\User$NC"
Write-Host "├── globalStorage"
Write-Host "│ ├── storage.json (已修改)"
Write-Host "│ └── backups"
# 列出备份文件
$backupFiles = Get-ChildItem "$BACKUP_DIR\*" -ErrorAction SilentlyContinue
if ($backupFiles) {
foreach ($file in $backupFiles) {
Write-Host "│ └── $($file.Name)"
}
} else {
Write-Host "│ └── (空)"
}
# 显示公众号信息
Write-Host ""
Write-Host "$GREEN================================$NC"
Write-Host "$YELLOW 关注公众号【煎饼果子卷AI】一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬) $NC"
Write-Host "$GREEN================================$NC"
Write-Host ""
Write-Host "$GREEN[信息]$NC 请重启 Cursor 以应用新的配置"
Write-Host ""
# 询问是否要禁用自动更新
Write-Host ""
Write-Host "$YELLOW[询问]$NC 是否要禁用 Cursor 自动更新功能?"
Write-Host "0) 否 - 保持默认设置 (按回车键)"
Write-Host "1) 是 - 禁用自动更新"
$choice = Read-Host "请输入选项 (0)"
if ($choice -eq "1") {
Write-Host ""
Write-Host "$GREEN[信息]$NC 正在处理自动更新..."
$updaterPath = "$env:LOCALAPPDATA\cursor-updater"
# 定义手动设置教程
function Show-ManualGuide {
Write-Host ""
Write-Host "$YELLOW[警告]$NC 自动设置失败,请尝试手动操作:"
Write-Host "$YELLOW手动禁用更新步骤:$NC"
Write-Host "1. 以管理员身份打开 PowerShell"
Write-Host "2. 复制粘贴以下命令:"
Write-Host "$BLUE命令1 - 删除现有目录(如果存在):$NC"
Write-Host "Remove-Item -Path `"$updaterPath`" -Force -Recurse -ErrorAction SilentlyContinue"
Write-Host ""
Write-Host "$BLUE命令2 - 创建阻止文件:$NC"
Write-Host "New-Item -Path `"$updaterPath`" -ItemType File -Force | Out-Null"
Write-Host ""
Write-Host "$BLUE命令3 - 设置只读属性:$NC"
Write-Host "Set-ItemProperty -Path `"$updaterPath`" -Name IsReadOnly -Value `$true"
Write-Host ""
Write-Host "$BLUE命令4 - 设置权限(可选):$NC"
Write-Host "icacls `"$updaterPath`" /inheritance:r /grant:r `"`$($env:USERNAME):(R)`""
Write-Host ""
Write-Host "$YELLOW验证方法:$NC"
Write-Host "1. 运行命令:Get-ItemProperty `"$updaterPath`""
Write-Host "2. 确认 IsReadOnly 属性为 True"
Write-Host "3. 运行命令:icacls `"$updaterPath`""
Write-Host "4. 确认只有读取权限"
Write-Host ""
Write-Host "$YELLOW[提示]$NC 完成后请重启 Cursor"
}
try {
# 检查cursor-updater是否存在
if (Test-Path $updaterPath) {
# 如果是文件,说明已经创建了阻止更新
if ((Get-Item $updaterPath) -is [System.IO.FileInfo]) {
Write-Host "$GREEN[信息]$NC 已创建阻止更新文件,无需再次阻止"
return
}
# 如果是目录,尝试删除
else {
try {
Remove-Item -Path $updaterPath -Force -Recurse -ErrorAction Stop
Write-Host "$GREEN[信息]$NC 成功删除 cursor-updater 目录"
}
catch {
Write-Host "$RED[错误]$NC 删除 cursor-updater 目录失败"
Show-ManualGuide
return
}
}
}
# 创建阻止文件
try {
New-Item -Path $updaterPath -ItemType File -Force -ErrorAction Stop | Out-Null
Write-Host "$GREEN[信息]$NC 成功创建阻止文件"
}
catch {
Write-Host "$RED[错误]$NC 创建阻止文件失败"
Show-ManualGuide
return
}
# 设置文件权限
try {
# 设置只读属性
Set-ItemProperty -Path $updaterPath -Name IsReadOnly -Value $true -ErrorAction Stop
# 使用 icacls 设置权限
$result = Start-Process "icacls.exe" -ArgumentList "`"$updaterPath`" /inheritance:r /grant:r `"$($env:USERNAME):(R)`"" -Wait -NoNewWindow -PassThru
if ($result.ExitCode -ne 0) {
throw "icacls 命令失败"
}
Write-Host "$GREEN[信息]$NC 成功设置文件权限"
}
catch {
Write-Host "$RED[错误]$NC 设置文件权限失败"
Show-ManualGuide
return
}
# 验证设置
try {
$fileInfo = Get-ItemProperty $updaterPath
if (-not $fileInfo.IsReadOnly) {
Write-Host "$RED[错误]$NC 验证失败:文件权限设置可能未生效"
Show-ManualGuide
return
}
}
catch {
Write-Host "$RED[错误]$NC 验证设置失败"
Show-ManualGuide
return
}
Write-Host "$GREEN[信息]$NC 成功禁用自动更新"
}
catch {
Write-Host "$RED[错误]$NC 发生未知错误: $_"
Show-ManualGuide
}
}
else {
Write-Host "$GREEN[信息]$NC 保持默认设置,不进行更改"
}
# 保留有效的注册表更新
Update-MachineGuid
} catch {
Write-Host "$RED[错误]$NC 主要操作失败: $_"
Write-Host "$YELLOW[尝试]$NC 使用备选方法..."
try {
# 备选方法:使用 Add-Content
$tempFile = [System.IO.Path]::GetTempFileName()
$config | ConvertTo-Json | Set-Content -Path $tempFile -Encoding UTF8
Copy-Item -Path $tempFile -Destination $STORAGE_FILE -Force
Remove-Item -Path $tempFile
Write-Host "$GREEN[信息]$NC 使用备选方法成功写入配置"
} catch {
Write-Host "$RED[错误]$NC 所有尝试都失败了"
Write-Host "错误详情: $_"
Write-Host "目标文件: $STORAGE_FILE"
Write-Host "请确保您有足够的权限访问该文件"
Read-Host "按回车键退出"
exit 1
}
}
Write-Host ""
Read-Host "按回车键退出"
exit 0
# 在文件写入部分修改
function Write-ConfigFile {
param($config, $filePath)
try {
# 使用 UTF8 无 BOM 编码
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
$jsonContent = $config | ConvertTo-Json -Depth 10
# 统一使用 LF 换行符
$jsonContent = $jsonContent.Replace("`r`n", "`n")
[System.IO.File]::WriteAllText(
[System.IO.Path]::GetFullPath($filePath),
$jsonContent,
$utf8NoBom
)
Write-Host "$GREEN[信息]$NC 成功写入配置文件(UTF8 无 BOM)"
}
catch {
throw "写入配置文件失败: $_"
}
}
Loading…
Cancel
Save