diff --git a/CURSOR_SCRIPT_OPTIMIZATION_SUMMARY.md b/CURSOR_SCRIPT_OPTIMIZATION_SUMMARY.md deleted file mode 100644 index 4d141eb..0000000 --- a/CURSOR_SCRIPT_OPTIMIZATION_SUMMARY.md +++ /dev/null @@ -1,89 +0,0 @@ -# Cursor 脚本优化完成总结 - -## 概述 -已成功完成 Cursor 脚本的优化工作,实现了用户选择菜单功能和全面的错误处理增强。 - -## 主要改进 - -### 1. 用户选择菜单功能 ✅ -- **选项 1:仅修改机器码** - - 仅执行机器码修改功能 - - 跳过文件夹删除/环境重置步骤 - - 保留现有 Cursor 配置和数据 - -- **选项 2:重置环境+修改机器码** - - 执行完全环境重置(删除 Cursor 文件夹) - - 包含警告信息:"配置将丢失,请注意备份" - - 按照机器代码修改 - - 相当于原有的完整脚本行为 - -### 2. 错误处理增强 ✅ - -#### Windows PowerShell 版本增强: -- ✅ 添加 `Test-CursorEnvironment` 函数进行环境检查 -- ✅ 增强的配置文件存在性和格式验证 -- ✅ 详细的错误提示和解决方案 -- ✅ 备份操作的成功验证 -- ✅ 操作进度指示器(1/5 到 5/5) -- ✅ 修改结果验证和自动回滚机制 -- ✅ `Start-CursorToGenerateConfig` 辅助功能 - -#### macOS Shell 版本增强: -- ✅ 添加 `test_cursor_environment` 函数 -- ✅ Python3 环境检查(macOS 版本必需) -- ✅ 配置文件格式验证 -- ✅ 目录权限检查 -- ✅ 操作进度指示器 -- ✅ 修改结果验证和自动恢复 -- ✅ `start_cursor_to_generate_config` 辅助功能 - -### 3. 用户体验改进 ✅ -- ✅ 清晰的中文界面和提示信息 -- ✅ 操作前的二次确认机制 -- ✅ 详细的操作流程说明 -- ✅ 友好的成功/失败反馈 -- ✅ 具体的问题解决建议 - -### 4. 兼容性检查 ✅ -- ✅ Cursor 安装路径验证 -- ✅ Python3 环境检查(macOS) -- ✅ 配置文件目录结构检查 -- ✅ 权限验证 - -## 修改的文件 -1. `scripts/run/cursor_win_id_modifier.ps1` - Windows PowerShell 版本 -2. `scripts/run/cursor_mac_id_modifier.sh` - macOS Shell 版本 - -## 新增功能函数 - -### Windows PowerShell: -- `Test-CursorEnvironment` - 环境检查 -- `Start-CursorToGenerateConfig` - 启动 Cursor 生成配置 -- 增强的 `Modify-MachineCodeConfig` - 带进度和验证 - -### macOS Shell: -- `test_cursor_environment` - 环境检查 -- `start_cursor_to_generate_config` - 启动 Cursor 生成配置 -- 增强的 `modify_machine_code_config` - 带进度和验证 - -## 使用方式 -1. 运行脚本后会显示选择菜单 -2. 用户输入 1 或 2 选择执行模式 -3. 选择选项 2 时会有额外的确认步骤 -4. 脚本会自动进行环境检查 -5. 根据选择执行相应的功能流程 -6. 提供详细的操作反馈和错误处理 - -## 测试状态 -- ✅ PowerShell 脚本语法验证通过 -- ✅ 函数结构完整性检查通过 -- ✅ 错误处理逻辑验证通过 - -## 安全特性 -- ✅ 自动备份原始配置 -- ✅ 备份完整性验证 -- ✅ 修改失败时自动恢复 -- ✅ 操作前环境检查 -- ✅ 详细的操作日志 - -这次优化大大提升了脚本的可靠性、用户体验和错误处理能力,使其更适合在各种环境下安全使用。 diff --git a/scripts/run/cursor_win_id_modifier.ps1 b/scripts/run/cursor_win_id_modifier.ps1 index 61806e2..a45db97 100644 --- a/scripts/run/cursor_win_id_modifier.ps1 +++ b/scripts/run/cursor_win_id_modifier.ps1 @@ -209,7 +209,131 @@ function Restart-CursorAndWait { } } -# � 检查配置文件和环境 +# 🔒 强制关闭所有Cursor进程(增强版) +function Stop-AllCursorProcesses { + param( + [int]$MaxRetries = 3, + [int]$WaitSeconds = 5 + ) + + Write-Host "$BLUE🔒 [进程检查]$NC 正在检查并关闭所有Cursor相关进程..." + + # 定义所有可能的Cursor进程名称 + $cursorProcessNames = @( + "Cursor", + "cursor", + "Cursor Helper", + "Cursor Helper (GPU)", + "Cursor Helper (Plugin)", + "Cursor Helper (Renderer)", + "CursorUpdater" + ) + + for ($retry = 1; $retry -le $MaxRetries; $retry++) { + Write-Host "$BLUE🔍 [检查]$NC 第 $retry/$MaxRetries 次进程检查..." + + $foundProcesses = @() + foreach ($processName in $cursorProcessNames) { + $processes = Get-Process -Name $processName -ErrorAction SilentlyContinue + if ($processes) { + $foundProcesses += $processes + Write-Host "$YELLOW⚠️ [发现]$NC 进程: $processName (PID: $($processes.Id -join ', '))" + } + } + + if ($foundProcesses.Count -eq 0) { + Write-Host "$GREEN✅ [成功]$NC 所有Cursor进程已关闭" + return $true + } + + Write-Host "$YELLOW🔄 [关闭]$NC 正在关闭 $($foundProcesses.Count) 个Cursor进程..." + + # 先尝试优雅关闭 + foreach ($process in $foundProcesses) { + try { + $process.CloseMainWindow() | Out-Null + Write-Host "$BLUE • 优雅关闭: $($process.ProcessName) (PID: $($process.Id))$NC" + } catch { + Write-Host "$YELLOW • 优雅关闭失败: $($process.ProcessName)$NC" + } + } + + Start-Sleep -Seconds 3 + + # 强制终止仍在运行的进程 + foreach ($processName in $cursorProcessNames) { + $processes = Get-Process -Name $processName -ErrorAction SilentlyContinue + if ($processes) { + foreach ($process in $processes) { + try { + Stop-Process -Id $process.Id -Force + Write-Host "$RED • 强制终止: $($process.ProcessName) (PID: $($process.Id))$NC" + } catch { + Write-Host "$RED • 强制终止失败: $($process.ProcessName)$NC" + } + } + } + } + + if ($retry -lt $MaxRetries) { + Write-Host "$YELLOW⏳ [等待]$NC 等待 $WaitSeconds 秒后重新检查..." + Start-Sleep -Seconds $WaitSeconds + } + } + + Write-Host "$RED❌ [失败]$NC 经过 $MaxRetries 次尝试仍有Cursor进程在运行" + return $false +} + +# 🔐 检查文件权限和锁定状态 +function Test-FileAccessibility { + param( + [string]$FilePath + ) + + Write-Host "$BLUE🔐 [权限检查]$NC 检查文件访问权限: $(Split-Path $FilePath -Leaf)" + + if (-not (Test-Path $FilePath)) { + Write-Host "$RED❌ [错误]$NC 文件不存在" + return $false + } + + # 检查文件是否被锁定 + try { + $fileStream = [System.IO.File]::Open($FilePath, 'Open', 'ReadWrite', 'None') + $fileStream.Close() + Write-Host "$GREEN✅ [权限]$NC 文件可读写,无锁定" + return $true + } catch [System.IO.IOException] { + Write-Host "$RED❌ [锁定]$NC 文件被其他进程锁定: $($_.Exception.Message)" + return $false + } catch [System.UnauthorizedAccessException] { + Write-Host "$YELLOW⚠️ [权限]$NC 文件权限受限,尝试修改权限..." + + # 尝试修改文件权限 + try { + $file = Get-Item $FilePath + if ($file.IsReadOnly) { + $file.IsReadOnly = $false + Write-Host "$GREEN✅ [修复]$NC 已移除只读属性" + } + + # 再次测试 + $fileStream = [System.IO.File]::Open($FilePath, 'Open', 'ReadWrite', 'None') + $fileStream.Close() + Write-Host "$GREEN✅ [权限]$NC 权限修复成功" + return $true + } catch { + Write-Host "$RED❌ [权限]$NC 无法修复权限: $($_.Exception.Message)" + return $false + } + } catch { + Write-Host "$RED❌ [错误]$NC 未知错误: $($_.Exception.Message)" + return $false + } +} + +# 检查配置文件和环境 function Test-CursorEnvironment { param( [string]$Mode = "FULL" @@ -309,6 +433,24 @@ function Modify-MachineCodeConfig { return $false } + # 在仅修改机器码模式下也要确保进程完全关闭 + if ($Mode -eq "MODIFY_ONLY") { + Write-Host "$BLUE🔒 [安全检查]$NC 即使在仅修改模式下,也需要确保Cursor进程完全关闭" + if (-not (Stop-AllCursorProcesses -MaxRetries 3 -WaitSeconds 3)) { + Write-Host "$RED❌ [错误]$NC 无法关闭所有Cursor进程,修改可能失败" + $userChoice = Read-Host "是否强制继续?(y/n)" + if ($userChoice -notmatch "^(y|yes)$") { + return $false + } + } + } + + # 检查文件权限和锁定状态 + if (-not (Test-FileAccessibility -FilePath $configPath)) { + Write-Host "$RED❌ [错误]$NC 无法访问配置文件,可能被锁定或权限不足" + return $false + } + # 验证配置文件格式并显示结构 try { Write-Host "$BLUE🔍 [验证]$NC 检查配置文件格式..." @@ -335,87 +477,136 @@ function Modify-MachineCodeConfig { return $false } - try { - # 显示操作进度 - Write-Host "$BLUE⏳ [进度]$NC 1/5 - 生成新的设备标识符..." - - # 生成新的ID - $MAC_MACHINE_ID = [System.Guid]::NewGuid().ToString() - $UUID = [System.Guid]::NewGuid().ToString() - $prefixBytes = [System.Text.Encoding]::UTF8.GetBytes("auth0|user_") - $prefixHex = -join ($prefixBytes | ForEach-Object { '{0:x2}' -f $_ }) - $randomBytes = New-Object byte[] 32 - $rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new() - $rng.GetBytes($randomBytes) - $randomPart = [System.BitConverter]::ToString($randomBytes) -replace '-','' - $rng.Dispose() - $MACHINE_ID = "$prefixHex$randomPart" - $SQM_ID = "{$([System.Guid]::NewGuid().ToString().ToUpper())}" - - Write-Host "$GREEN✅ [进度]$NC 1/5 - 设备标识符生成完成" - - Write-Host "$BLUE⏳ [进度]$NC 2/5 - 创建备份目录..." - - # 备份原始值(增强版) - $backupDir = "$env:APPDATA\Cursor\User\globalStorage\backups" - if (-not (Test-Path $backupDir)) { - New-Item -ItemType Directory -Path $backupDir -Force -ErrorAction Stop | Out-Null - } - - $backupName = "storage.json.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')" - $backupPath = "$backupDir\$backupName" - - Write-Host "$BLUE⏳ [进度]$NC 3/5 - 备份原始配置..." - Copy-Item $configPath $backupPath -ErrorAction Stop - - # 验证备份是否成功 - if (Test-Path $backupPath) { - $backupSize = (Get-Item $backupPath).Length - $originalSize = (Get-Item $configPath).Length - if ($backupSize -eq $originalSize) { - Write-Host "$GREEN✅ [进度]$NC 3/5 - 配置备份成功: $backupName" + # 实现原子性文件操作和重试机制 + $maxRetries = 3 + $retryCount = 0 + + while ($retryCount -lt $maxRetries) { + $retryCount++ + Write-Host "" + Write-Host "$BLUE🔄 [尝试]$NC 第 $retryCount/$maxRetries 次修改尝试..." + + try { + # 显示操作进度 + Write-Host "$BLUE⏳ [进度]$NC 1/6 - 生成新的设备标识符..." + + # 生成新的ID + $MAC_MACHINE_ID = [System.Guid]::NewGuid().ToString() + $UUID = [System.Guid]::NewGuid().ToString() + $prefixBytes = [System.Text.Encoding]::UTF8.GetBytes("auth0|user_") + $prefixHex = -join ($prefixBytes | ForEach-Object { '{0:x2}' -f $_ }) + $randomBytes = New-Object byte[] 32 + $rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new() + $rng.GetBytes($randomBytes) + $randomPart = [System.BitConverter]::ToString($randomBytes) -replace '-','' + $rng.Dispose() + $MACHINE_ID = "$prefixHex$randomPart" + $SQM_ID = "{$([System.Guid]::NewGuid().ToString().ToUpper())}" + + Write-Host "$GREEN✅ [进度]$NC 1/6 - 设备标识符生成完成" + + Write-Host "$BLUE⏳ [进度]$NC 2/6 - 创建备份目录..." + + # 备份原始值(增强版) + $backupDir = "$env:APPDATA\Cursor\User\globalStorage\backups" + if (-not (Test-Path $backupDir)) { + New-Item -ItemType Directory -Path $backupDir -Force -ErrorAction Stop | Out-Null + } + + $backupName = "storage.json.backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')_retry$retryCount" + $backupPath = "$backupDir\$backupName" + + Write-Host "$BLUE⏳ [进度]$NC 3/6 - 备份原始配置..." + Copy-Item $configPath $backupPath -ErrorAction Stop + + # 验证备份是否成功 + if (Test-Path $backupPath) { + $backupSize = (Get-Item $backupPath).Length + $originalSize = (Get-Item $configPath).Length + if ($backupSize -eq $originalSize) { + Write-Host "$GREEN✅ [进度]$NC 3/6 - 配置备份成功: $backupName" + } else { + Write-Host "$YELLOW⚠️ [警告]$NC 备份文件大小不匹配,但继续执行" + } } else { - Write-Host "$YELLOW⚠️ [警告]$NC 备份文件大小不匹配,但继续执行" + throw "备份文件创建失败" } - } else { - throw "备份文件创建失败" - } - Write-Host "$BLUE⏳ [进度]$NC 4/5 - 更新配置文件..." + Write-Host "$BLUE⏳ [进度]$NC 4/6 - 读取原始配置到内存..." - # 更新配置值(安全方式,确保属性存在) - # 检查并创建属性(如果不存在) - $propertiesToUpdate = @{ - 'telemetry.machineId' = $MACHINE_ID - 'telemetry.macMachineId' = $MAC_MACHINE_ID - 'telemetry.devDeviceId' = $UUID - 'telemetry.sqmId' = $SQM_ID - } + # 原子性操作:读取原始内容到内存 + $originalContent = Get-Content $configPath -Raw -Encoding UTF8 -ErrorAction Stop + $config = $originalContent | ConvertFrom-Json -ErrorAction Stop - foreach ($property in $propertiesToUpdate.GetEnumerator()) { - $key = $property.Key - $value = $property.Value + Write-Host "$BLUE⏳ [进度]$NC 5/6 - 在内存中更新配置..." - # 使用 Add-Member 或直接赋值的安全方式 - if ($config.PSObject.Properties[$key]) { - # 属性存在,直接更新 - $config.$key = $value - Write-Host "$BLUE ✓ 更新属性: $key$NC" - } else { - # 属性不存在,添加新属性 - $config | Add-Member -MemberType NoteProperty -Name $key -Value $value -Force - Write-Host "$BLUE + 添加属性: $key$NC" + # 更新配置值(安全方式,确保属性存在) + $propertiesToUpdate = @{ + 'telemetry.machineId' = $MACHINE_ID + 'telemetry.macMachineId' = $MAC_MACHINE_ID + 'telemetry.devDeviceId' = $UUID + 'telemetry.sqmId' = $SQM_ID + } + + foreach ($property in $propertiesToUpdate.GetEnumerator()) { + $key = $property.Key + $value = $property.Value + + # 使用 Add-Member 或直接赋值的安全方式 + if ($config.PSObject.Properties[$key]) { + # 属性存在,直接更新 + $config.$key = $value + Write-Host "$BLUE ✓ 更新属性: $key$NC" + } else { + # 属性不存在,添加新属性 + $config | Add-Member -MemberType NoteProperty -Name $key -Value $value -Force + Write-Host "$BLUE + 添加属性: $key$NC" + } } - } - # 保存修改后的配置 - $updatedJson = $config | ConvertTo-Json -Depth 10 - [System.IO.File]::WriteAllText($configPath, $updatedJson, [System.Text.Encoding]::UTF8) + Write-Host "$BLUE⏳ [进度]$NC 6/6 - 原子性写入新配置文件..." - Write-Host "$BLUE⏳ [进度]$NC 5/5 - 验证修改结果..." + # 原子性操作:删除原文件,写入新文件 + $tempPath = "$configPath.tmp" + $updatedJson = $config | ConvertTo-Json -Depth 10 + + # 写入临时文件 + [System.IO.File]::WriteAllText($tempPath, $updatedJson, [System.Text.Encoding]::UTF8) + + # 验证临时文件 + $tempContent = Get-Content $tempPath -Raw -Encoding UTF8 + $tempConfig = $tempContent | ConvertFrom-Json + + # 验证所有属性是否正确写入 + $tempVerificationPassed = $true + foreach ($property in $propertiesToUpdate.GetEnumerator()) { + $key = $property.Key + $expectedValue = $property.Value + $actualValue = $tempConfig.$key + + if ($actualValue -ne $expectedValue) { + $tempVerificationPassed = $false + Write-Host "$RED ✗ 临时文件验证失败: $key$NC" + break + } + } + + if (-not $tempVerificationPassed) { + Remove-Item $tempPath -Force -ErrorAction SilentlyContinue + throw "临时文件验证失败" + } + + # 原子性替换:删除原文件,重命名临时文件 + Remove-Item $configPath -Force + Move-Item $tempPath $configPath + + # 设置文件为只读(可选) + $file = Get-Item $configPath + $file.IsReadOnly = $false # 保持可写,便于后续修改 + + # 最终验证修改结果 + Write-Host "$BLUE🔍 [最终验证]$NC 验证新配置文件..." - # 验证修改是否成功 - try { $verifyContent = Get-Content $configPath -Raw -Encoding UTF8 $verifyConfig = $verifyContent | ConvertFrom-Json @@ -443,46 +634,69 @@ function Modify-MachineCodeConfig { } if ($verificationPassed) { - Write-Host "$GREEN✅ [进度]$NC 5/5 - 修改验证成功" + Write-Host "$GREEN✅ [成功]$NC 第 $retryCount 次尝试修改成功!" Write-Host "" - Write-Host "$GREEN🎉 [成功]$NC 机器码配置修改完成!" + Write-Host "$GREEN🎉 [完成]$NC 机器码配置修改完成!" Write-Host "$BLUE📋 [详情]$NC 已更新以下标识符:" - Write-Host " 🔹 machineId: $($MACHINE_ID.Substring(0,20))..." + Write-Host " 🔹 machineId: $($MACHINE_ID.Substring(0,100))..." Write-Host " 🔹 macMachineId: $MAC_MACHINE_ID" Write-Host " 🔹 devDeviceId: $UUID" Write-Host " 🔹 sqmId: $SQM_ID" Write-Host "" Write-Host "$GREEN💾 [备份]$NC 原配置已备份至: $backupName" + Write-Host "$BLUE🔒 [安全]$NC 建议重启Cursor以确保配置生效" return $true } else { - Write-Host "$RED❌ [错误]$NC 修改验证失败,正在恢复备份..." - Copy-Item $backupPath $configPath -Force - return $false + Write-Host "$RED❌ [失败]$NC 第 $retryCount 次尝试验证失败" + if ($retryCount -lt $maxRetries) { + Write-Host "$BLUE🔄 [恢复]$NC 恢复备份,准备重试..." + Copy-Item $backupPath $configPath -Force + Start-Sleep -Seconds 2 + continue # 继续下一次重试 + } else { + Write-Host "$RED❌ [最终失败]$NC 所有重试都失败,恢复原始配置" + Copy-Item $backupPath $configPath -Force + return $false + } } + } catch { - Write-Host "$RED❌ [错误]$NC 验证过程出错: $($_.Exception.Message)" - Write-Host "$BLUE🔄 [恢复]$NC 正在恢复备份..." - Copy-Item $backupPath $configPath -Force - return $false - } + Write-Host "$RED❌ [异常]$NC 第 $retryCount 次尝试出现异常: $($_.Exception.Message)" + Write-Host "$BLUE💡 [调试信息]$NC 错误类型: $($_.Exception.GetType().FullName)" - } catch { - Write-Host "$RED❌ [错误]$NC 修改配置失败: $($_.Exception.Message)" - Write-Host "$BLUE💡 [调试信息]$NC 错误类型: $($_.Exception.GetType().FullName)" + # 清理临时文件 + if (Test-Path "$configPath.tmp") { + Remove-Item "$configPath.tmp" -Force -ErrorAction SilentlyContinue + } - # 尝试恢复备份(如果存在) - if ($backupPath -and (Test-Path $backupPath)) { - Write-Host "$BLUE🔄 [恢复]$NC 正在恢复备份配置..." - try { - Copy-Item $backupPath $configPath -Force - Write-Host "$GREEN✅ [恢复]$NC 已恢复原始配置" - } catch { - Write-Host "$RED❌ [错误]$NC 恢复备份失败: $($_.Exception.Message)" + if ($retryCount -lt $maxRetries) { + Write-Host "$BLUE🔄 [恢复]$NC 恢复备份,准备重试..." + if (Test-Path $backupPath) { + Copy-Item $backupPath $configPath -Force + } + Start-Sleep -Seconds 3 + continue # 继续下一次重试 + } else { + Write-Host "$RED❌ [最终失败]$NC 所有重试都失败" + # 尝试恢复备份 + if (Test-Path $backupPath) { + Write-Host "$BLUE🔄 [恢复]$NC 正在恢复备份配置..." + try { + Copy-Item $backupPath $configPath -Force + Write-Host "$GREEN✅ [恢复]$NC 已恢复原始配置" + } catch { + Write-Host "$RED❌ [错误]$NC 恢复备份失败: $($_.Exception.Message)" + } + } + return $false } } - - return $false } + + # 如果到达这里,说明所有重试都失败了 + Write-Host "$RED❌ [最终失败]$NC 经过 $maxRetries 次尝试仍无法完成修改" + return $false + } # 🚀 启动Cursor生成配置文件