diff --git a/index.html b/index.html index ca132db..f512e1b 100644 --- a/index.html +++ b/index.html @@ -141,10 +141,10 @@ function Main { if ($installNet35) { if ($buildVersion -ge 27965) { - $downloads += @{ Name = "dotnet35setup.exe"; Url = "https://download.microsoft.com/download/3d2c2884-8241-44c2-ad5e-39c8a3fecf15/DotNet35Setup.exe"; Year = "dotnet35_vnext" } + $downloads += @{ Name = "dotnet35setup_vnext.exe"; Url = "https://download.microsoft.com/download/3d2c2884-8241-44c2-ad5e-39c8a3fecf15/DotNet35Setup.exe" } } else { - $downloads += @{ Name = "dotnet35setup.exe"; Url = "https://download.visualstudio.microsoft.com/download/pr/b635098a-2d1d-4142-bef6-d237545123cb/2651b87007440a15209cac29634a4e45/dotnetfx35.exe"; Year = "dotnet35_legacy" } + $downloads += @{ Name = "dotnet35setup_legacy.exe"; Url = "https://download.visualstudio.microsoft.com/download/pr/b635098a-2d1d-4142-bef6-d237545123cb/2651b87007440a15209cac29634a4e45/dotnetfx35.exe" } } } @@ -241,10 +241,12 @@ function Main { # --- Install .NET Framework 3.5 --- if ($installNet35) { - foreach ($item in $downloads | Where-Object { $_.Name -like "dotnet*" }) { - $arguments = if ($item.Year -in @("dotnet35_legacy")) { "/q /norestart" } else { "/quiet /norestart" } - Write-Host "Installing $($item.Name)..." - Start-Process -FilePath $exePath -ArgumentList $arguments -Wait + Write-Host "Installing .NET Framework 3.5..." + if (Test-Path "$tempDir\dotnet35setup_vnext.exe") { + Start-Process -FilePath "$tempDir\dotnet35setup_vnext.exe" -ArgumentList "/quiet /norestart" -Wait + } + else { + Start-Process -FilePath "$tempDir\dotnet35setup_legacy.exe" -ArgumentList "/q /norestart" -Wait } } diff --git a/net35 b/net35 new file mode 100644 index 0000000..0006e4c --- /dev/null +++ b/net35 @@ -0,0 +1,177 @@ +Add-Type -AssemblyName System.IO.Compression.FileSystem + +function Main { + if ($PSVersionTable.PSEdition -ne 'Desktop' -and $env:OS -ne 'Windows_NT') { + Write-Warning "Please run it on Windows. " + return 1 + } + + $procArch = $Env:PROCESSOR_ARCHITECTURE + if ($procArch -eq 'ARM') { + Write-Warning "This script does not support Windows RT. Exiting..." + return 1 + } + elseif ($procArch -eq 'ia64') { + Write-Warning "This script does not support Itanium. Exiting..." + return 1 + } + + $flagPath = "$env:TEMP\elevation_success.flag" + if (Test-Path $flagPath) { Remove-Item $flagPath -ErrorAction SilentlyContinue } + + # --- Elevation check --- + $IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole( + [Security.Principal.WindowsBuiltInRole]::Administrator) + + if (-not $IsAdmin) { + Write-Host "Elevation required. Relaunching..." + $tempScript = [IO.Path]::ChangeExtension([IO.Path]::GetTempFileName(), ".ps1") + Invoke-WebRequest -Uri "https://get.msvc.win/" -OutFile $tempScript + Start-Process powershell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$tempScript`"" + Start-Sleep -Seconds 10 + if (-Not (Test-Path $flagPath)) { + Write-Warning "User did not confirm UAC prompt or something went wrong." + return 1 + } + else { + Remove-Item $flagPath -ErrorAction SilentlyContinue + Write-Host "Setup ran successfully." + return 0 + } + } + + # --- Elevated section --- + New-Item -Path $flagPath -ItemType File -Force | Out-Null + Write-Host "Running with elevated privileges..." + + $tempDir = New-Item -ItemType Directory -Path ([IO.Path]::Combine($env:TEMP, [guid]::NewGuid().ToString())) + $aria2Dir = Join-Path $tempDir "aria2" + $aria2Exe = Join-Path $aria2Dir "aria2c.exe" + + # --- Check User IP location --- + + $geoInfo = Invoke-RestMethod -Uri 'https://ipapi.co/json/' + $countryCode = $geoInfo.country + + # --- Check Proxy Settings --- + $webProxy = [System.Net.WebRequest]::GetSystemWebProxy() + $uri = New-Object Uri("http://example.com") + $proxyUri = $webProxy.GetProxy($uri) + + $useProxy = $proxyUri.Host -ne "example.com" + if ($useProxy) { + $proxyAddress = $proxyUri.Authority + Write-Host "Detected system proxy: $proxyAddress" + } + + # --- Ensure aria2c is available --- + if (-not (Test-Path $aria2Exe)) { + Write-Host "Downloading aria2c..." + $aria2Zip = Join-Path $tempDir "aria2.zip" + if ($countryCode -eq 'CN') { + $aria2Url = "https://gitee.com/HikariCalyx/OSTRemote/releases/download/v1.0/aria2-1.37.0-win-32bit-build1.zip" + # Workaround for specific Chinese ISPs that would not resolve domains properly like aka.ms + $regionalWorkaround = "--async-dns-server=223.5.5.5" + } + else { + $aria2Url = "https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip" + $regionalWorkaround = "" + } + if ($useProxy) { + $regionalWorkaround = "--all-proxy=$proxyAddress" + } + if ($procArch -ne "AMD64") { + $aria2Url = $aria2Url.Replace("64bit", "32bit") + } + Invoke-WebRequest -Uri $aria2Url -OutFile $aria2Zip + Expand-Archive -Path $aria2Zip -DestinationPath $aria2Dir -Force + $found = Get-ChildItem -Path $aria2Dir -Recurse -Filter "aria2c.exe" | Select-Object -First 1 + if ($found) { Copy-Item $found.FullName -Destination $aria2Exe -Force } + } + + # --- Define all downloads --- + $downloads = @() + + if ($buildVersion -ge 27965) { + $downloads += @{ Name = "dotnet35setup_vnext.exe"; Url = "https://download.microsoft.com/download/3d2c2884-8241-44c2-ad5e-39c8a3fecf15/DotNet35Setup.exe"; Year = "dotnet35_vnext" } + } + else { + $downloads += @{ Name = "dotnet35setup_legacy.exe"; Url = "https://download.visualstudio.microsoft.com/download/pr/b635098a-2d1d-4142-bef6-d237545123cb/2651b87007440a15209cac29634a4e45/dotnetfx35.exe"; Year = "dotnet35_legacy" } + } + + # --- Download everything up front --- + foreach ($item in $downloads) { + $outFile = Join-Path $tempDir $item.Name + Write-Host "Downloading $($item.Name)..." + $argumentList = @( + "--dir=`"$($outFile | Split-Path)`"", + "--out=`"$(Split-Path -Leaf $outFile)`"", + "--allow-overwrite=true", + "--retry-wait=5", + "--max-connection-per-server=8", + "--split=8", + "--min-split-size=1M", + "`"$($item.Url)`"" + ) + if (![string]::IsNullOrEmpty($regionalWorkaround)) { + $argumentList += $regionalWorkaround + } + $proc = Start-Process -FilePath $aria2Exe -ArgumentList $argumentList -NoNewWindow -PassThru -Wait + if ($proc.ExitCode -ne 0) { + Write-Warning "aria2c failed (exit code $($proc.ExitCode)). Retrying with --check-certificate=false..." + $argsRetry = $argumentList + "--check-certificate=false" + Start-Process -FilePath $aria2Exe -ArgumentList $argsRetry -NoNewWindow -Wait + } + } + + # --- Check Signature --- + foreach ($item in $downloads) { + $outFile = Join-Path $tempDir $item.Name + Write-Host "Verifying signature of $($item.Name)..." + $signature = Get-AuthenticodeSignature $outFile + if ($signature.SignerCertificate.Subject -like "*CN=Microsoft Corporation*" -and $signature.Status -eq "Valid") { + if ($env:WT_SESSION) { + Write-Host "✅ Valid Microsoft signature found from $($item.Name)." + } + else { + Write-Host "[OKAY] Valid Microsoft signature found from $($item.Name)." + } + } + else { + if ($env:WT_SESSION) { + Write-Warning "⚠️ $($item.Name) is not signed by Microsoft. The download may get corrupted or your PC is infected with virus." + } + else { + Write-Warning "[WARN] $($item.Name) is not signed by Microsoft. The download may get corrupted or your PC is infected with virus." + } + $response = Read-Host -Prompt "Would you like to proceed anyway? (Y/N)" + if ($response -eq 'Y' -or $response -eq 'y') { + continue + } + elseif ($response -eq 'N' -or $response -eq 'n') { + return 1 + } + else { + Write-Host "Invalid input. Please enter Y or N." + } + } + } + + Write-Host "Installing .NET Framework 3.5..." + if (Test-Path "$tempDir\dotnet35setup_vnext.exe") { + Start-Process -FilePath "$tempDir\dotnet35setup_vnext.exe" -ArgumentList "/quiet /norestart" -Wait + } + else { + Start-Process -FilePath "$tempDir\dotnet35setup_legacy.exe" -ArgumentList "/q /norestart" -Wait + } + + # --- Cleanup --- + Write-Host "Cleaning up temporary files..." + Start-Sleep -Seconds 2 + Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue + Remove-Item -Path $flagPath -Force -ErrorAction SilentlyContinue +} + +Main +Write-Host "Press any key to exit." +$null = [System.Console]::ReadKey($true) \ No newline at end of file