mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-10-08 11:39:10 +11:00
Add friendly explanations for common DISM exit codes (#5087)
* Add friendly explanations for common DISM exit codes Invoke-WinUtilISODism threw only a raw exit code on DISM failure (e.g. "DISM add-driver failed with exit code 112"), leaving users to look up what the number means themselves. Adds a $knownExitCode lookup table mapping common Windows/DISM exit codes (disk full, access denied, file/path not found, file in use, timeout, etc.) to plain-English explanations. When a failure's exit code is recognized, the thrown message now includes the explanation in parentheses; unrecognized codes fall back to the original plain-number message. Verified the script still parses correctly after the change. * Add missing period to fallback DISM error message * Add tests for DISM known/unknown exit code error messages Adds a test verifying a known exit code (112) produces the friendly explanation in the thrown message, alongside the existing test verifying an unrecognized code still falls back to the plain numeric message. Verified: all 35 tests in win11creator.Tests.ps1 pass. * Document DISM friendly error messages in Win11 Creator troubleshooting Adds a Troubleshooting table row explaining the new DISM error message format (exit code + explanation in parentheses), with guidance for the most common cases and a link to Microsoft's full error code reference for anything not explained. * Fix duplicate DISM calls in unmapped exit code test The unmapped-code test called Invoke-WinUtilISOScript twice — once via Should -Throw, once to capture the message for the no-parens check — causing $script:dismCalls to double-count. Consolidated to a single call, checking both the exit code and the absence of a parenthesized explanation against one captured exception message. Verified: all 36 tests in win11creator.Tests.ps1 pass. * Fix broken DISM error code reference link in docs Replaced the dead windows-hardware/manufacture link with Microsoft's actual System Error Codes reference page, which DISM exit codes correspond to. * Strengthen DISM fallback regression coverage --------- Co-authored-by: Chris Titus <contact@christitus.com>
This commit is contained in:
@@ -950,6 +950,109 @@ Describe "Win11 Creator setup media" {
|
||||
}
|
||||
}
|
||||
|
||||
It "reports a friendly explanation when DISM fails with a known exit code" {
|
||||
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoMountFailureKnownCode_$([guid]::NewGuid())"
|
||||
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
||||
$script:dismCalls = [System.Collections.Generic.List[string]]::new()
|
||||
|
||||
function dism.exe {
|
||||
param([Parameter(ValueFromRemainingArguments)][string[]]$Arguments)
|
||||
|
||||
$script:dismCalls.Add(($Arguments -join '|'))
|
||||
if ($Arguments -contains '/Get-WimInfo') {
|
||||
$global:LASTEXITCODE = 0
|
||||
'Languages : en-US'
|
||||
'Installation : Client'
|
||||
'Edition : Professional'
|
||||
'ProductSuite : Terminal Server'
|
||||
'ProductType : WinNT'
|
||||
} elseif ($Arguments -contains '/Mount-Image') {
|
||||
$global:LASTEXITCODE = 112
|
||||
'Mount failed'
|
||||
} elseif ($Arguments -contains '/Get-MountedImageInfo') {
|
||||
$global:LASTEXITCODE = 0
|
||||
"Mount Dir : $(Join-Path (Split-Path -Path $contentRoot -Parent) 'wim_mount')"
|
||||
} elseif ($Arguments -contains '/Export-Driver') {
|
||||
$global:LASTEXITCODE = 0
|
||||
Export-WinUtilTestDriverPackage -Arguments $Arguments -Fixtures @(
|
||||
@{ Path = 'storage_pkg'; Name = 'iaStorAC.inf'; Class = 'System' }
|
||||
)
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
New-Item -Path (Split-Path $installWim -Parent) -ItemType Directory -Force | Out-Null
|
||||
Set-Content -Path $installWim -Value 'mock-wim'
|
||||
. $script:isoScriptPath
|
||||
|
||||
{ Invoke-WinUtilISOScript -ISOContentsDir $contentRoot -AutoUnattendXml $template -InjectCurrentSystemDrivers $true -InstallImagePath $installWim -InstallImageIndex 6 -InstallEditionId 'Professional' } |
|
||||
Should -Throw '*112*Disk is full*'
|
||||
|
||||
@($script:dismCalls | Where-Object { $_ -match '/Get-MountedImageInfo' }).Count | Should -Be 1
|
||||
@($script:dismCalls | Where-Object { $_ -match '/Unmount-Image\|.*\|/Discard' }).Count | Should -Be 1
|
||||
} finally {
|
||||
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $contentRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "falls back to the plain exit code for an unmapped DISM failure" {
|
||||
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoMountFailureUnknownCode_$([guid]::NewGuid())"
|
||||
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
||||
$script:dismCalls = [System.Collections.Generic.List[string]]::new()
|
||||
|
||||
function dism.exe {
|
||||
param([Parameter(ValueFromRemainingArguments)][string[]]$Arguments)
|
||||
|
||||
$script:dismCalls.Add(($Arguments -join '|'))
|
||||
if ($Arguments -contains '/Get-WimInfo') {
|
||||
$global:LASTEXITCODE = 0
|
||||
'Languages : en-US'
|
||||
'Installation : Client'
|
||||
'Edition : Professional'
|
||||
'ProductSuite : Terminal Server'
|
||||
'ProductType : WinNT'
|
||||
} elseif ($Arguments -contains '/Mount-Image') {
|
||||
$global:LASTEXITCODE = 999
|
||||
'Mount failed'
|
||||
} elseif ($Arguments -contains '/Get-MountedImageInfo') {
|
||||
$global:LASTEXITCODE = 0
|
||||
"Mount Dir : $(Join-Path (Split-Path -Path $contentRoot -Parent) 'wim_mount')"
|
||||
} elseif ($Arguments -contains '/Export-Driver') {
|
||||
$global:LASTEXITCODE = 0
|
||||
Export-WinUtilTestDriverPackage -Arguments $Arguments -Fixtures @(
|
||||
@{ Path = 'storage_pkg'; Name = 'iaStorAC.inf'; Class = 'System' }
|
||||
)
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
New-Item -Path (Split-Path $installWim -Parent) -ItemType Directory -Force | Out-Null
|
||||
Set-Content -Path $installWim -Value 'mock-wim'
|
||||
. $script:isoScriptPath
|
||||
|
||||
$thrown = $null
|
||||
try {
|
||||
Invoke-WinUtilISOScript -ISOContentsDir $contentRoot -AutoUnattendXml $template -InjectCurrentSystemDrivers $true -InstallImagePath $installWim -InstallImageIndex 6 -InstallEditionId 'Professional'
|
||||
} catch {
|
||||
$thrown = $_.Exception.Message
|
||||
}
|
||||
$thrown | Should -Be 'DISM mount failed with exit code 999.'
|
||||
|
||||
@($script:dismCalls | Where-Object { $_ -match '/Get-MountedImageInfo' }).Count | Should -Be 1
|
||||
@($script:dismCalls | Where-Object { $_ -match '/Unmount-Image\|.*\|/Discard' }).Count | Should -Be 1
|
||||
} finally {
|
||||
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path $contentRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
It "does not add driver setup artifacts when injection is disabled" {
|
||||
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoNoDrivers_$([guid]::NewGuid())"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user