fix(dism-progress): make percent parser locale-safe and resilient

- Accept “4.9%” and “4,9%”; strip %; use integer part only
- Prevent conversion warnings; steady progress output
This commit is contained in:
shaun.greatbatch
2025-09-19 16:09:01 +01:00
parent 2e1fc4816a
commit e3c2d6c074

View File

@ -230,13 +230,11 @@ function Invoke-DismWithProgress {
$outf = Join-Path $env:TEMP "dism_out_$ts.txt" $outf = Join-Path $env:TEMP "dism_out_$ts.txt"
$errf = Join-Path $env:TEMP "dism_err_$ts.txt" $errf = Join-Path $env:TEMP "dism_err_$ts.txt"
# Ensure we get a log file too (helps debugging)
if (-not ($Arguments -match '/LogPath:')) { if (-not ($Arguments -match '/LogPath:')) {
$logFile = Join-Path $env:TEMP "dism_log_$ts.log" $logFile = Join-Path $env:TEMP "dism_log_$ts.log"
$Arguments += "/LogPath:$logFile" $Arguments += "/LogPath:$logFile"
} }
# Launch DISM and redirect output so we can parse percentages safely
$p = Start-Process -FilePath dism.exe ` $p = Start-Process -FilePath dism.exe `
-ArgumentList ($Arguments -join ' ') ` -ArgumentList ($Arguments -join ' ') `
-NoNewWindow ` -NoNewWindow `
@ -247,18 +245,21 @@ function Invoke-DismWithProgress {
$lastPct = -1 $lastPct = -1
while (-not $p.HasExited) { while (-not $p.HasExited) {
if (Test-Path $outf) { if (Test-Path $outf) {
# Read current output and grab the latest percentage like "63.8%" or "63%"
$content = Get-Content -Path $outf -Raw -ErrorAction SilentlyContinue $content = Get-Content -Path $outf -Raw -ErrorAction SilentlyContinue
if ($content) { if ($content) {
$m = [regex]::Matches($content, '(\d{1,3}(?:\.\d+)?)%') # Capture "NN", optionally followed by decimal with . or , then %
# Examples matched: "4.9%", "4,9 %", "62%" -> group 1 = integer part
$m = [regex]::Matches($content, '(\d{1,3})(?:[.,]\d+)?\s*%')
if ($m.Count -gt 0) { if ($m.Count -gt 0) {
$pct = [int][math]::Min(100, [double]$m[$m.Count-1].Groups[1].Value) $pctText = $m[$m.Count-1].Groups[1].Value
$pct = 0
[void][int]::TryParse($pctText, [ref]$pct)
if ($pct -gt 100) { $pct = 100 }
if ($pct -ne $lastPct) { if ($pct -ne $lastPct) {
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "$pct%" -PercentComplete $pct Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "$pct%" -PercentComplete $pct
$lastPct = $pct $lastPct = $pct
} }
} else { } else {
# No explicit percent yet<65>show a spinner
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "Working..." -PercentComplete 0 Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "Working..." -PercentComplete 0
} }
} }
@ -266,17 +267,13 @@ function Invoke-DismWithProgress {
Start-Sleep -Milliseconds 400 Start-Sleep -Milliseconds 400
} }
# Complete the bar cleanly
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Completed Write-Progress -Activity "DISM $($Arguments -join ' ')" -Completed
$exit = $p.ExitCode $exit = $p.ExitCode
# Show a quick summary if it failed
if ($exit -ne 0) { if ($exit -ne 0) {
Write-Warning "DISM exited with code $exit" Write-Warning "DISM exited with code $exit"
if (Test-Path $errf) { Get-Content $errf -Tail 25 | Write-Warning } if (Test-Path $errf) { Get-Content $errf -Tail 25 | Write-Warning }
} }
return $exit return $exit
} }