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"
$errf = Join-Path $env:TEMP "dism_err_$ts.txt"
# Ensure we get a log file too (helps debugging)
if (-not ($Arguments -match '/LogPath:')) {
$logFile = Join-Path $env:TEMP "dism_log_$ts.log"
$Arguments += "/LogPath:$logFile"
}
# Launch DISM and redirect output so we can parse percentages safely
$p = Start-Process -FilePath dism.exe `
-ArgumentList ($Arguments -join ' ') `
-NoNewWindow `
@ -247,18 +245,21 @@ function Invoke-DismWithProgress {
$lastPct = -1
while (-not $p.HasExited) {
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
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) {
$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) {
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "$pct%" -PercentComplete $pct
$lastPct = $pct
}
} else {
# No explicit percent yet<65>show a spinner
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Status "Working..." -PercentComplete 0
}
}
@ -266,17 +267,13 @@ function Invoke-DismWithProgress {
Start-Sleep -Milliseconds 400
}
# Complete the bar cleanly
Write-Progress -Activity "DISM $($Arguments -join ' ')" -Completed
$exit = $p.ExitCode
# Show a quick summary if it failed
if ($exit -ne 0) {
Write-Warning "DISM exited with code $exit"
if (Test-Path $errf) { Get-Content $errf -Tail 25 | Write-Warning }
}
return $exit
}