Download Chrome with curl.exe, then BITS, then Invoke-WebRequest
Invoke-WebRequest pushes every buffer through the pipeline and is the slowest of the three by a wide margin; curl.exe ships in System32 on every supported Windows and resumes a partial file with -C -, which matters on a 166 MB download that gets interrupted. Also checks the finished file against Content-Length, because a truncated MSI fails in msiexec with an error that says nothing about why. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f52efd73c6
commit
61d6305ded
@@ -92,20 +92,52 @@ if (-not $Remove -and -not (Find-Chrome)) {
|
|||||||
|
|
||||||
# Google's own enterprise MSI, which installs machine-wide and silently. We
|
# Google's own enterprise MSI, which installs machine-wide and silently. We
|
||||||
# are already elevated by this point, so this needs no second prompt.
|
# are already elevated by this point, so this needs no second prompt.
|
||||||
|
$url = 'https://dl.google.com/dl/chrome/install/googlechromestandaloneenterprise64.msi'
|
||||||
$msi = Join-Path $env:TEMP 'googlechromestandaloneenterprise64.msi'
|
$msi = Join-Path $env:TEMP 'googlechromestandaloneenterprise64.msi'
|
||||||
Write-Host 'Google Chrome is not installed — downloading it from Google (about 160 MB).'
|
Write-Host 'Google Chrome is not installed — downloading it from Google (about 160 MB).'
|
||||||
|
|
||||||
# Progress off for the duration. Windows PowerShell re-renders the progress
|
# Three ways down, fastest first. Invoke-WebRequest is last for a reason: it
|
||||||
# bar on every buffer, which on a 160 MB file costs far more time than the
|
# pushes every buffer through the PowerShell pipeline, and on Windows
|
||||||
# transfer itself — minutes instead of seconds, looking for all the world
|
# PowerShell it also re-renders the progress bar each time, which on a file
|
||||||
# like a stalled download.
|
# this size costs more than the transfer itself — minutes rather than
|
||||||
$previousProgress = $ProgressPreference
|
# seconds, and indistinguishable from a stall while you watch it crawl.
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
$curl = Join-Path $env:SystemRoot 'System32\curl.exe'
|
||||||
|
if (Test-Path $curl) {
|
||||||
|
# -C - resumes a part-downloaded file rather than starting the 160 MB
|
||||||
|
# again, which matters when this is retried after an interruption.
|
||||||
|
& $curl -fL --retry 3 --retry-delay 2 -C - -o $msi $url
|
||||||
|
if ($LASTEXITCODE -ne 0) { Remove-Item $msi -ErrorAction SilentlyContinue }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $msi) -and (Get-Command Start-BitsTransfer -ErrorAction SilentlyContinue)) {
|
||||||
|
try {
|
||||||
|
Start-BitsTransfer -Source $url -Destination $msi -Priority Foreground -ErrorAction Stop
|
||||||
|
} catch {
|
||||||
|
Write-Host "BITS transfer failed ($($_.Exception.Message)); falling back."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path $msi)) {
|
||||||
|
$previousProgress = $ProgressPreference
|
||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing
|
||||||
|
} finally {
|
||||||
|
$ProgressPreference = $previousProgress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# A truncated download installs as a corrupt package, with an msiexec error
|
||||||
|
# that says nothing about the real cause.
|
||||||
|
$expected = 0
|
||||||
try {
|
try {
|
||||||
Invoke-WebRequest -Uri 'https://dl.google.com/dl/chrome/install/googlechromestandaloneenterprise64.msi' `
|
$expected = [int64](Invoke-WebRequest -Uri $url -Method Head -UseBasicParsing).Headers['Content-Length']
|
||||||
-OutFile $msi -UseBasicParsing
|
} catch { }
|
||||||
} finally {
|
$got = (Get-Item $msi -ErrorAction SilentlyContinue).Length
|
||||||
$ProgressPreference = $previousProgress
|
if (-not $got) { throw 'Chrome download produced no file.' }
|
||||||
|
if ($expected -gt 0 -and $got -ne $expected) {
|
||||||
|
Remove-Item $msi -ErrorAction SilentlyContinue
|
||||||
|
throw "Chrome download is incomplete ($got of $expected bytes). Re-run to resume."
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host 'Installing Chrome...'
|
Write-Host 'Installing Chrome...'
|
||||||
|
|||||||
Reference in New Issue
Block a user