mirror of
https://github.com/yuaotian/go-cursor-help.git
synced 2025-06-08 12:32:06 +08:00
feat: Enhance configuration management and process handling in main.go
- Added TelemetrySqmId to StorageConfig for improved telemetry tracking. - Modified NewStorageConfig to accept an existing configuration, allowing for better state management. - Updated getConfigPath, saveConfig, and readExistingConfig functions to include username as a parameter for user-specific configuration handling. - Implemented ensureCursorClosed function to ensure the Cursor application is closed before proceeding. - Enhanced process management functions to handle both uppercase and lowercase process names for better compatibility across systems. - Updated README.md with new installation instructions and manual configuration steps for the added TelemetrySqmId. These changes collectively improve the application's configuration handling and user experience during setup and operation.
This commit is contained in:
parent
6cc28518b4
commit
5fb0288420
58
README.md
58
README.md
@ -6,15 +6,13 @@
|
|||||||
[](https://github.com/yuaotian/go-cursor-help/blob/main/LICENSE)
|
[](https://github.com/yuaotian/go-cursor-help/blob/main/LICENSE)
|
||||||
[](https://github.com/yuaotian/go-cursor-help/stargazers)
|
[](https://github.com/yuaotian/go-cursor-help/stargazers)
|
||||||
|
|
||||||
[English](#english) | [中文](#chinese)
|
[English](#-english) | [中文](#-chinese)
|
||||||
|
|
||||||
<img src="https://ai-cursor.com/wp-content/uploads/2024/09/logo-cursor-ai-png.webp" alt="Cursor Logo" width="120"/>
|
<img src="https://ai-cursor.com/wp-content/uploads/2024/09/logo-cursor-ai-png.webp" alt="Cursor Logo" width="120"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a name="english"></a>
|
# 🌟 English
|
||||||
|
|
||||||
## 🌟 English
|
|
||||||
|
|
||||||
### 📝 Description
|
### 📝 Description
|
||||||
|
|
||||||
@ -35,6 +33,8 @@ this is a mistake.
|
|||||||
|
|
||||||
### 📥 Installation
|
### 📥 Installation
|
||||||
|
|
||||||
|
#### Automatic Installation
|
||||||
|
|
||||||
**Linux/macOS**
|
**Linux/macOS**
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/install.sh | bash -s -- --auto-sudo && rm -f /tmp/cursor_id_modifier_*
|
curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/install.sh | bash -s -- --auto-sudo && rm -f /tmp/cursor_id_modifier_*
|
||||||
@ -45,6 +45,27 @@ curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/
|
|||||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/bin/cursor_id_modifier_v2.0.0_windows_amd64.exe')); Remove-Item -Path "$env:TEMP\cursor-id-modifier.exe" -ErrorAction SilentlyContinue
|
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/bin/cursor_id_modifier_v2.0.0_windows_amd64.exe')); Remove-Item -Path "$env:TEMP\cursor-id-modifier.exe" -ErrorAction SilentlyContinue
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Manual Method
|
||||||
|
|
||||||
|
1. Close Cursor completely
|
||||||
|
2. Navigate to the configuration file location:
|
||||||
|
- Windows: `%APPDATA%\Cursor\User\globalStorage\storage.json`
|
||||||
|
- macOS: `~/Library/Application Support/Cursor/User/globalStorage/storage.json`
|
||||||
|
- Linux: `~/.config/Cursor/User/globalStorage/storage.json`
|
||||||
|
3. Create a backup of `storage.json`
|
||||||
|
4. Edit `storage.json` and update these fields with new random UUIDs:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"telemetry.machineId": "generate-new-uuid",
|
||||||
|
"telemetry.macMachineId": "generate-new-uuid",
|
||||||
|
"telemetry.devDeviceId": "generate-new-uuid",
|
||||||
|
"telemetry.sqmId": "generate-new-uuid",
|
||||||
|
"lastModified": "2024-01-01T00:00:00.000Z",
|
||||||
|
"version": "1.0.1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
5. Save the file and restart Cursor
|
||||||
|
|
||||||
### 🔧 Technical Details
|
### 🔧 Technical Details
|
||||||
|
|
||||||
The program modifies Cursor's `storage.json` config file:
|
The program modifies Cursor's `storage.json` config file:
|
||||||
@ -56,12 +77,11 @@ Generates new unique identifiers for:
|
|||||||
- `telemetry.machineId`
|
- `telemetry.machineId`
|
||||||
- `telemetry.macMachineId`
|
- `telemetry.macMachineId`
|
||||||
- `telemetry.devDeviceId`
|
- `telemetry.devDeviceId`
|
||||||
|
- `telemetry.sqmId`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<a name="chinese"></a>
|
# 🌏 Chinese
|
||||||
|
|
||||||
## 🌏 中文
|
|
||||||
|
|
||||||
### 📝 问题描述
|
### 📝 问题描述
|
||||||
|
|
||||||
@ -82,6 +102,8 @@ this is a mistake.
|
|||||||
|
|
||||||
### 📥 安装方法
|
### 📥 安装方法
|
||||||
|
|
||||||
|
#### 自动安装
|
||||||
|
|
||||||
**Linux/macOS**
|
**Linux/macOS**
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/install.sh | bash -s -- --auto-sudo && rm -f /tmp/cursor_id_modifier_*
|
curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/install.sh | bash -s -- --auto-sudo && rm -f /tmp/cursor_id_modifier_*
|
||||||
@ -92,6 +114,27 @@ curl -fsSL https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/
|
|||||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/bin/cursor_id_modifier_v2.0.0_windows_amd64.exe')); Remove-Item -Path "$env:TEMP\cursor-id-modifier.exe" -ErrorAction SilentlyContinue
|
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/bin/cursor_id_modifier_v2.0.0_windows_amd64.exe')); Remove-Item -Path "$env:TEMP\cursor-id-modifier.exe" -ErrorAction SilentlyContinue
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 手动方法
|
||||||
|
|
||||||
|
1. 完全关闭 Cursor
|
||||||
|
2. 找到配置文件位置:
|
||||||
|
- Windows: `%APPDATA%\Cursor\User\globalStorage\storage.json`
|
||||||
|
- macOS: `~/Library/Application Support/Cursor/User/globalStorage/storage.json`
|
||||||
|
- Linux: `~/.config/Cursor/User/globalStorage/storage.json`
|
||||||
|
3. 备份 `storage.json`
|
||||||
|
4. 编辑 `storage.json` 并更新以下字段(使用新的随机UUID):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"telemetry.machineId": "生成新的uuid",
|
||||||
|
"telemetry.macMachineId": "生成新的uuid",
|
||||||
|
"telemetry.devDeviceId": "生成新的uuid",
|
||||||
|
"telemetry.sqmId": "生成新的uuid",
|
||||||
|
"lastModified": "2024-01-01T00:00:00.000Z",
|
||||||
|
"version": "1.0.1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
5. 保存文件并重启 Cursor
|
||||||
|
|
||||||
### 🔧 技术细节
|
### 🔧 技术细节
|
||||||
|
|
||||||
程序修改Cursor的`storage.json`配置文件:
|
程序修改Cursor的`storage.json`配置文件:
|
||||||
@ -103,6 +146,7 @@ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManage
|
|||||||
- `telemetry.machineId`
|
- `telemetry.machineId`
|
||||||
- `telemetry.macMachineId`
|
- `telemetry.macMachineId`
|
||||||
- `telemetry.devDeviceId`
|
- `telemetry.devDeviceId`
|
||||||
|
- `telemetry.sqmId`
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
|
203
main.go
203
main.go
@ -63,10 +63,10 @@ type (
|
|||||||
TelemetryMacMachineId string `json:"telemetry.macMachineId"`
|
TelemetryMacMachineId string `json:"telemetry.macMachineId"`
|
||||||
TelemetryMachineId string `json:"telemetry.machineId"`
|
TelemetryMachineId string `json:"telemetry.machineId"`
|
||||||
TelemetryDevDeviceId string `json:"telemetry.devDeviceId"`
|
TelemetryDevDeviceId string `json:"telemetry.devDeviceId"`
|
||||||
|
TelemetrySqmId string `json:"telemetry.sqmId"` // Added TelemetrySqmId
|
||||||
LastModified time.Time `json:"lastModified"`
|
LastModified time.Time `json:"lastModified"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppError defines error types / 定义错误类型
|
// AppError defines error types / 定义错误类型
|
||||||
AppError struct {
|
AppError struct {
|
||||||
Type string
|
Type string
|
||||||
@ -152,35 +152,26 @@ func (e *AppError) Error() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Configuration Functions / 配置函数
|
// Configuration Functions / 配置函数
|
||||||
func NewStorageConfig() *StorageConfig {
|
func NewStorageConfig(oldConfig *StorageConfig) *StorageConfig { // Modified to take old config
|
||||||
return &StorageConfig{
|
newConfig := &StorageConfig{
|
||||||
TelemetryMacMachineId: generateMachineId(),
|
TelemetryMacMachineId: generateMachineId(),
|
||||||
TelemetryMachineId: generateMachineId(),
|
TelemetryMachineId: generateMachineId(),
|
||||||
TelemetryDevDeviceId: generateDevDeviceId(),
|
TelemetryDevDeviceId: generateDevDeviceId(),
|
||||||
LastModified: time.Now(),
|
LastModified: time.Now(),
|
||||||
Version: Version,
|
Version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldConfig != nil {
|
||||||
|
newConfig.TelemetrySqmId = oldConfig.TelemetrySqmId
|
||||||
|
} else {
|
||||||
|
newConfig.TelemetrySqmId = generateMachineId()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() *Config {
|
if newConfig.TelemetrySqmId == "" {
|
||||||
return &Config{
|
newConfig.TelemetrySqmId = generateMachineId()
|
||||||
Storage: StorageConfig{
|
|
||||||
Version: Version,
|
|
||||||
},
|
|
||||||
UI: UIConfig{
|
|
||||||
Language: detectLanguage(),
|
|
||||||
Theme: "default",
|
|
||||||
Spinner: SpinnerConfig{
|
|
||||||
Frames: []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"},
|
|
||||||
Delay: 100 * time.Millisecond,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
System: SystemConfig{
|
|
||||||
RetryAttempts: 3,
|
|
||||||
RetryDelay: time.Second,
|
|
||||||
Timeout: 30 * time.Second,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return newConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID Generation Functions / ID生成函数
|
// ID Generation Functions / ID生成函数
|
||||||
@ -205,22 +196,16 @@ func generateDevDeviceId() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// File Operations / 文件操作
|
// File Operations / 文件操作
|
||||||
func getConfigPath() (string, error) {
|
func getConfigPath(username string) (string, error) { // Modified to take username
|
||||||
var configDir string
|
var configDir string
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
configDir = filepath.Join(os.Getenv("APPDATA"), "Cursor", "User", "globalStorage")
|
configDir = filepath.Join(os.Getenv("APPDATA"), "Cursor", "User", "globalStorage")
|
||||||
case "darwin":
|
case "darwin":
|
||||||
homeDir, err := os.UserHomeDir()
|
homeDir := filepath.Join("/home/", username)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
configDir = filepath.Join(homeDir, "Library", "Application Support", "Cursor", "User", "globalStorage")
|
configDir = filepath.Join(homeDir, "Library", "Application Support", "Cursor", "User", "globalStorage")
|
||||||
case "linux":
|
case "linux":
|
||||||
homeDir, err := os.UserHomeDir()
|
homeDir := filepath.Join("/home/", username)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
configDir = filepath.Join(homeDir, ".config", "Cursor", "User", "globalStorage")
|
configDir = filepath.Join(homeDir, ".config", "Cursor", "User", "globalStorage")
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
return "", fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||||
@ -228,8 +213,8 @@ func getConfigPath() (string, error) {
|
|||||||
return filepath.Join(configDir, "storage.json"), nil
|
return filepath.Join(configDir, "storage.json"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveConfig(config *StorageConfig) error {
|
func saveConfig(config *StorageConfig, username string) error { // Modified to take username
|
||||||
configPath, err := getConfigPath()
|
configPath, err := getConfigPath(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -307,8 +292,8 @@ func saveConfig(config *StorageConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readExistingConfig() (*StorageConfig, error) {
|
func readExistingConfig(username string) (*StorageConfig, error) { // Modified to take username
|
||||||
configPath, err := getConfigPath()
|
configPath, err := getConfigPath(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -368,38 +353,71 @@ func (pm *ProcessManager) killWindowsProcess(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pm *ProcessManager) killUnixProcess(ctx context.Context) error {
|
func (pm *ProcessManager) killUnixProcess(ctx context.Context) error {
|
||||||
|
// Search for the process by it's executable name (AppRun) in ps output
|
||||||
|
cmd := exec.CommandContext(ctx, "ps", "aux")
|
||||||
|
output, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute ps command: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(string(output), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.Contains(line, "AppRun") {
|
||||||
|
parts := strings.Fields(line)
|
||||||
|
if len(parts) > 1 {
|
||||||
|
pid := parts[1]
|
||||||
|
if err := pm.forceKillProcess(ctx, pid); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle lowercase
|
||||||
|
if strings.Contains(line, "apprun") {
|
||||||
|
parts := strings.Fields(line)
|
||||||
|
if len(parts) > 1 {
|
||||||
|
pid := parts[1]
|
||||||
|
if err := pm.forceKillProcess(ctx, pid); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to kill process by pid
|
||||||
|
func (pm *ProcessManager) forceKillProcess(ctx context.Context, pid string) error {
|
||||||
// First try graceful termination
|
// First try graceful termination
|
||||||
if err := exec.CommandContext(ctx, "pkill", "-TERM", "-f", "Cursor").Run(); err == nil {
|
if err := exec.CommandContext(ctx, "kill", pid).Run(); err == nil {
|
||||||
// Wait for processes to terminate gracefully
|
// Wait for processes to terminate gracefully
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force kill if still running
|
// Force kill if still running
|
||||||
if err := exec.CommandContext(ctx, "pkill", "-KILL", "-f", "Cursor").Run(); err == nil {
|
if err := exec.CommandContext(ctx, "kill", "-9", pid).Run(); err != nil {
|
||||||
time.Sleep(1 * time.Second)
|
return fmt.Errorf("failed to force kill process %s: %w", pid, err)
|
||||||
}
|
|
||||||
|
|
||||||
// Also try lowercase variant
|
|
||||||
exec.CommandContext(ctx, "pkill", "-KILL", "-f", "cursor").Run()
|
|
||||||
|
|
||||||
// Verify no processes are left
|
|
||||||
if output, err := exec.CommandContext(ctx, "pgrep", "-f", "Cursor").Output(); err == nil && len(output) > 0 {
|
|
||||||
return errors.New("cursor processes still running after kill attempts")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkCursorRunning() bool {
|
func checkCursorRunning() bool {
|
||||||
var cmd *exec.Cmd
|
cmd := exec.Command("ps", "aux")
|
||||||
if runtime.GOOS == "windows" {
|
output, err := cmd.Output()
|
||||||
cmd = exec.Command("tasklist", "/FI", "IMAGENAME eq Cursor.exe", "/NH")
|
if err != nil {
|
||||||
} else {
|
return false
|
||||||
cmd = exec.Command("pgrep", "-f", "Cursor")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output, _ := cmd.Output()
|
lines := strings.Split(string(output), "\n")
|
||||||
return strings.Contains(string(output), "Cursor") || strings.Contains(string(output), "cursor")
|
for _, line := range lines {
|
||||||
|
if strings.Contains(line, "AppRun") || strings.Contains(line, "apprun") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI Components / UI组件
|
// UI Components / UI组件
|
||||||
@ -458,7 +476,15 @@ func showSuccess() {
|
|||||||
// Add spacing before config location
|
// Add spacing before config location
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
|
||||||
if configPath, err := getConfigPath(); err == nil {
|
username := os.Getenv("SUDO_USER")
|
||||||
|
if username == "" {
|
||||||
|
user, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
username = user.Username
|
||||||
|
}
|
||||||
|
if configPath, err := getConfigPath(username); err == nil {
|
||||||
pathColor.Printf("%s\n%s\n", text.ConfigLocation, configPath)
|
pathColor.Printf("%s\n%s\n", text.ConfigLocation, configPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -620,7 +646,29 @@ func waitExit() {
|
|||||||
bufio.NewReader(os.Stdin).ReadString('\n')
|
bufio.NewReader(os.Stdin).ReadString('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main Function / 主函数
|
// Add this new function near the other process management functions
|
||||||
|
func ensureCursorClosed() error {
|
||||||
|
maxAttempts := 3
|
||||||
|
|
||||||
|
for attempt := 1; attempt <= maxAttempts; attempt++ {
|
||||||
|
if !checkCursorRunning() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentLanguage == EN {
|
||||||
|
fmt.Printf("\nPlease close Cursor before continuing. Attempt %d/%d\n", attempt, maxAttempts)
|
||||||
|
fmt.Println("Waiting 5 seconds...")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\n请在继续之前关闭 Cursor。尝试 %d/%d\n", attempt, maxAttempts)
|
||||||
|
fmt.Println("等待 5 秒...")
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("cursor is still running")
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Initialize error recovery
|
// Initialize error recovery
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -631,9 +679,25 @@ func main() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var username string
|
||||||
|
if username = os.Getenv("SUDO_USER"); username == "" {
|
||||||
|
user, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
username = user.Username
|
||||||
|
}
|
||||||
|
log.Println("Current user: ", username)
|
||||||
|
|
||||||
// Initialize configuration
|
// Initialize configuration
|
||||||
config := initConfig()
|
ui := NewUI(&UIConfig{
|
||||||
ui := NewUI(&config.UI)
|
Language: detectLanguage(),
|
||||||
|
Theme: "default",
|
||||||
|
Spinner: SpinnerConfig{
|
||||||
|
Frames: []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"},
|
||||||
|
Delay: 100 * time.Millisecond,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Check privileges
|
// Check privileges
|
||||||
os.Stdout.Sync()
|
os.Stdout.Sync()
|
||||||
@ -665,6 +729,17 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add this block after the privilege check
|
||||||
|
if err := ensureCursorClosed(); err != nil {
|
||||||
|
if currentLanguage == EN {
|
||||||
|
fmt.Println("\nError: Please close Cursor manually before running this program.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("\n错误:请在运行此程序之前手动关闭 Cursor。")
|
||||||
|
}
|
||||||
|
waitExit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Process management
|
// Process management
|
||||||
pm := &ProcessManager{
|
pm := &ProcessManager{
|
||||||
config: &SystemConfig{
|
config: &SystemConfig{
|
||||||
@ -707,12 +782,12 @@ func main() {
|
|||||||
printCyberpunkBanner()
|
printCyberpunkBanner()
|
||||||
|
|
||||||
// Read and update configuration
|
// Read and update configuration
|
||||||
oldConfig, err := readExistingConfig()
|
oldConfig, err := readExistingConfig(username) // add username parameter
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oldConfig = nil
|
oldConfig = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
storageConfig, err := loadAndUpdateConfig(ui)
|
storageConfig, err := loadAndUpdateConfig(ui, username) // add username parameter
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleError(err)
|
handleError(err)
|
||||||
waitExit()
|
waitExit()
|
||||||
@ -722,7 +797,7 @@ func main() {
|
|||||||
// Show changes and save
|
// Show changes and save
|
||||||
showIdComparison(oldConfig, storageConfig)
|
showIdComparison(oldConfig, storageConfig)
|
||||||
|
|
||||||
if err := saveConfig(storageConfig); err != nil {
|
if err := saveConfig(storageConfig, username); err != nil { // add username parameter
|
||||||
handleError(err)
|
handleError(err)
|
||||||
waitExit()
|
waitExit()
|
||||||
return
|
return
|
||||||
@ -822,12 +897,13 @@ func showIdComparison(oldConfig *StorageConfig, newConfig *StorageConfig) {
|
|||||||
yellow.Printf("Machine ID: %s\n", newConfig.TelemetryMachineId)
|
yellow.Printf("Machine ID: %s\n", newConfig.TelemetryMachineId)
|
||||||
yellow.Printf("Mac Machine ID: %s\n", newConfig.TelemetryMacMachineId)
|
yellow.Printf("Mac Machine ID: %s\n", newConfig.TelemetryMacMachineId)
|
||||||
yellow.Printf("Dev Device ID: %s\n", newConfig.TelemetryDevDeviceId)
|
yellow.Printf("Dev Device ID: %s\n", newConfig.TelemetryDevDeviceId)
|
||||||
|
yellow.Printf("SQM ID: %s\n", newConfig.TelemetrySqmId)
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration functions / 配置函数
|
// Configuration functions / 配置函数
|
||||||
func loadAndUpdateConfig(ui *UI) (*StorageConfig, error) {
|
func loadAndUpdateConfig(ui *UI, username string) (*StorageConfig, error) { // add username parameter
|
||||||
configPath, err := getConfigPath()
|
configPath, err := getConfigPath(username) // add username parameter
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -835,7 +911,7 @@ func loadAndUpdateConfig(ui *UI) (*StorageConfig, error) {
|
|||||||
text := texts[currentLanguage]
|
text := texts[currentLanguage]
|
||||||
ui.showProgress(text.ReadingConfig)
|
ui.showProgress(text.ReadingConfig)
|
||||||
|
|
||||||
_, err = os.ReadFile(configPath)
|
oldConfig, err := readExistingConfig(username) // add username parameter
|
||||||
if err != nil && !os.IsNotExist(err) {
|
if err != nil && !os.IsNotExist(err) {
|
||||||
return nil, &AppError{
|
return nil, &AppError{
|
||||||
Type: ErrSystem,
|
Type: ErrSystem,
|
||||||
@ -846,6 +922,5 @@ func loadAndUpdateConfig(ui *UI) (*StorageConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ui.showProgress(text.GeneratingIds)
|
ui.showProgress(text.GeneratingIds)
|
||||||
return NewStorageConfig(), nil
|
return NewStorageConfig(oldConfig), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user