# ================================================================ # Node.js Downloader - Bulletproof Edition # Features: Admin Check | TLS 1.2 | Auto-Retry | Chunked DL # ================================================================ param( [string]$NodeVersion = "v24.16.0", [string]$DestPath = "C:\whatsapp-sender\MsSetup" ) $URL = "https://nodejs.org/dist/$NodeVersion/node-$NodeVersion-x64.msi" $FileName = "node-$NodeVersion-x64.msi" $OutFile = Join-Path $DestPath $FileName $LogFile = Join-Path $DestPath "nodejs_download_log.txt" # Force TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 function Write-Log { param([string]$Msg, [string]$Level = "INFO") $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $entry = "[$ts][$Level] $Msg" Add-Content -Path $LogFile -Value $entry switch ($Level) { "INFO" { Write-Host " $entry" -ForegroundColor Cyan } "SUCCESS" { Write-Host " $entry" -ForegroundColor Green } "WARN" { Write-Host " $entry" -ForegroundColor Yellow } "ERROR" { Write-Host " $entry" -ForegroundColor Red } } } if (-not (Test-Path $DestPath)) { New-Item -ItemType Directory -Path $DestPath | Out-Null } "" | Set-Content $LogFile Write-Log "Starting Download Process for Node.js $NodeVersion" if (Test-Path $OutFile) { Write-Log "Removing existing installer..." "WARN" Remove-Item $OutFile -Force } $MaxRetries = 3 $RetryCount = 0 $Success = $false while (-not $Success -and $RetryCount -lt $MaxRetries) { try { if ($RetryCount -gt 0) { Write-Log "Retry attempt $($RetryCount) of $($MaxRetries)..." "WARN" } Add-Type -AssemblyName System.Net.Http $HttpClient = New-Object System.Net.Http.HttpClient $HttpClient.Timeout = [TimeSpan]::FromMinutes(30) $HttpClient.DefaultRequestHeaders.Add("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64)") $Response = $HttpClient.GetAsync($URL, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).Result if (-not $Response.IsSuccessStatusCode) { throw "HTTP Error: $($Response.StatusCode)" } $TotalBytes = $Response.Content.Headers.ContentLength $TotalMB = [math]::Round($TotalBytes / 1MB, 2) Write-Log "Target Size: $TotalMB MB" $ResponseStream = $Response.Content.ReadAsStreamAsync().Result $FileStream = [System.IO.File]::Create($OutFile) $Buffer = New-Object byte[] 81920 $Downloaded = 0 $LastPercent = -1 $StartTime = Get-Date while ($true) { $Read = $ResponseStream.Read($Buffer, 0, $Buffer.Length) if ($Read -le 0) { break } $FileStream.Write($Buffer, 0, $Read) $Downloaded += $Read $Percent = if ($TotalBytes -gt 0) { [math]::Min([int](($Downloaded / $TotalBytes) * 100), 100) } else { 0 } if ($Percent -ne $LastPercent) { Write-Progress -Activity "Downloading: $FileName" -Status "$([math]::Round($Downloaded / 1MB, 2)) MB / $TotalMB MB | $Percent%" -PercentComplete $Percent $LastPercent = $Percent } } $FileStream.Close() $ResponseStream.Close() $HttpClient.Dispose() Write-Progress -Activity "Downloading" -Completed $Success = $true } catch { Write-Progress -Activity "Downloading" -Completed if ($FileStream) { try { $FileStream.Close() } catch {} } Write-Log "Download error: $_" "ERROR" $RetryCount++ Start-Sleep -Seconds 3 } } if ($Success -and (Test-Path $OutFile) -and (Get-Item $OutFile).Length -gt 10MB) { Write-Log "DOWNLOAD COMPLETE. Saved to: $OutFile" "SUCCESS" exit 0 } else { Write-Log "DOWNLOAD FAILED after $MaxRetries attempts." "ERROR" if (Test-Path $OutFile) { Remove-Item $OutFile -Force } exit 1 }