diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 2df2833..c46c2af 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1,4 +1,4 @@ -# 設置顏色主題 +# set color theme $Theme = @{ Primary = 'Cyan' Success = 'Green' @@ -17,7 +17,7 @@ $Logo = @" ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ "@ -# 美化輸出函數 +# Beautiful Output Function function Write-Styled { param ( [string]$Message, @@ -40,7 +40,7 @@ function Write-Styled { } } -# 獲取版本號函數 +# Get version number function function Get-LatestVersion { try { $latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest" @@ -54,28 +54,28 @@ function Get-LatestVersion { } } -# 顯示 Logo +# Show Logo Write-Host $Logo -ForegroundColor $Theme.Primary $releaseInfo = Get-LatestVersion $version = $releaseInfo.Version Write-Host "Version $version" -ForegroundColor $Theme.Info Write-Host "Created by YeongPin`n" -ForegroundColor $Theme.Info -# 設置 TLS 1.2 +# Set TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -# 主安裝函數 +# Main installation function function Install-CursorFreeVIP { Write-Styled "Start downloading Cursor Free VIP" -Color $Theme.Primary -Prefix "Download" try { - # 獲取最新版本 + # Get latest version Write-Styled "Checking latest version..." -Color $Theme.Primary -Prefix "Update" $releaseInfo = Get-LatestVersion $version = $releaseInfo.Version Write-Styled "Found latest version: $version" -Color $Theme.Success -Prefix "Version" - # 查找對應的資源 + # Find corresponding resources $asset = $releaseInfo.Assets | Where-Object { $_.name -eq "CursorFreeVIP_${version}_windows.exe" } if (!$asset) { Write-Styled "File not found: CursorFreeVIP_${version}_windows.exe" -Color $Theme.Error -Prefix "Error" @@ -86,22 +86,114 @@ function Install-CursorFreeVIP { throw "Cannot find target file" } - # 下載到Downloads文件夾 + # Check if Downloads folder already exists for the corresponding version $DownloadsPath = [Environment]::GetFolderPath("UserProfile") + "\Downloads" - $downloadPath = Join-Path $DownloadsPath "CursorFreeVIP.exe" + $downloadPath = Join-Path $DownloadsPath "CursorFreeVIP_${version}_windows.exe" - Write-Styled "Downloading to Downloads folder..." -Color $Theme.Primary -Prefix "Download" + if (Test-Path $downloadPath) { + Write-Styled "Found existing installation file" -Color $Theme.Success -Prefix "Found" + Write-Styled "Location: $downloadPath" -Color $Theme.Info -Prefix "Location" + + # Check if running with administrator privileges + $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + + if (-not $isAdmin) { + Write-Styled "Requesting administrator privileges..." -Color $Theme.Warning -Prefix "Admin" + + # Create new process with administrator privileges + $startInfo = New-Object System.Diagnostics.ProcessStartInfo + $startInfo.FileName = $downloadPath + $startInfo.UseShellExecute = $true + $startInfo.Verb = "runas" + + try { + [System.Diagnostics.Process]::Start($startInfo) + Write-Styled "Program started with admin privileges" -Color $Theme.Success -Prefix "Launch" + return + } + catch { + Write-Styled "Failed to start with admin privileges. Starting normally..." -Color $Theme.Warning -Prefix "Warning" + Start-Process $downloadPath + return + } + } + + # If already running with administrator privileges, start directly + Start-Process $downloadPath + return + } + + Write-Styled "No existing installation file found, starting download..." -Color $Theme.Primary -Prefix "Download" + + # Create WebClient and add progress event $webClient = New-Object System.Net.WebClient $webClient.Headers.Add("User-Agent", "PowerShell Script") - $webClient.DownloadFile($asset.browser_download_url, $downloadPath) + + # Define progress variables + $Global:downloadedBytes = 0 + $Global:totalBytes = 0 + $Global:lastProgress = 0 + $Global:lastBytes = 0 + $Global:lastTime = Get-Date + + # Download progress event + $eventId = [guid]::NewGuid() + Register-ObjectEvent -InputObject $webClient -EventName DownloadProgressChanged -Action { + $Global:downloadedBytes = $EventArgs.BytesReceived + $Global:totalBytes = $EventArgs.TotalBytesToReceive + $progress = [math]::Round(($Global:downloadedBytes / $Global:totalBytes) * 100, 1) + + # Only update display when progress changes by more than 1% + if ($progress -gt $Global:lastProgress + 1) { + $Global:lastProgress = $progress + $downloadedMB = [math]::Round($Global:downloadedBytes / 1MB, 2) + $totalMB = [math]::Round($Global:totalBytes / 1MB, 2) + + # Calculate download speed + $currentTime = Get-Date + $timeSpan = ($currentTime - $Global:lastTime).TotalSeconds + if ($timeSpan -gt 0) { + $bytesChange = $Global:downloadedBytes - $Global:lastBytes + $speed = $bytesChange / $timeSpan + + # Choose appropriate unit based on speed + $speedDisplay = if ($speed -gt 1MB) { + "$([math]::Round($speed / 1MB, 2)) MB/s" + } elseif ($speed -gt 1KB) { + "$([math]::Round($speed / 1KB, 2)) KB/s" + } else { + "$([math]::Round($speed, 2)) B/s" + } + + Write-Host "`rDownloading: $downloadedMB MB / $totalMB MB ($progress%) - $speedDisplay" -NoNewline -ForegroundColor Cyan + + # Update last data + $Global:lastBytes = $Global:downloadedBytes + $Global:lastTime = $currentTime + } + } + } | Out-Null + + # Download completed event + Register-ObjectEvent -InputObject $webClient -EventName DownloadFileCompleted -Action { + Write-Host "`r" -NoNewline + Write-Styled "Download completed!" -Color $Theme.Success -Prefix "Complete" + Unregister-Event -SourceIdentifier $eventId + } | Out-Null + + # Start download + $webClient.DownloadFileAsync([Uri]$asset.browser_download_url, $downloadPath) + + # Wait for download to complete + while ($webClient.IsBusy) { + Start-Sleep -Milliseconds 100 + } - Write-Styled "Download completed!" -Color $Theme.Success -Prefix "Complete" Write-Styled "File location: $downloadPath" -Color $Theme.Info -Prefix "Location" Write-Styled "Starting program..." -Color $Theme.Primary -Prefix "Launch" - # 運行程序 + # Run program Start-Process $downloadPath - } catch { Write-Styled $_.Exception.Message -Color $Theme.Error -Prefix "Error" @@ -109,7 +201,7 @@ function Install-CursorFreeVIP { } } -# 執行安裝 +# Execute installation try { Install-CursorFreeVIP } @@ -120,4 +212,4 @@ catch { finally { Write-Host "`nPress any key to exit..." -ForegroundColor $Theme.Info $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') -} \ No newline at end of file +}