expand ui and fix clean and reset

This commit is contained in:
Chris Titus
2026-02-25 11:44:02 -06:00
parent 64ea075727
commit 669ecd9c64
2 changed files with 143 additions and 60 deletions

View File

@@ -376,6 +376,7 @@ function Invoke-WinUtilISOModify {
# the UI thread here. # the UI thread here.
$sync["WPFWin11ISOOutputSection"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOOutputSection"].Dispatcher.Invoke([action]{
$sync["WPFWin11ISOOutputSection"].Visibility = "Visible" $sync["WPFWin11ISOOutputSection"].Visibility = "Visible"
$sync["WPFWin11ISOStatusLog"].Height = 300
}) })
} }
catch { catch {
@@ -480,12 +481,13 @@ function Invoke-WinUtilISOCheckExistingWork {
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed" $sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed" $sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
$sync["WPFWin11ISOOutputSection"].Visibility = "Visible" $sync["WPFWin11ISOOutputSection"].Visibility = "Visible"
$sync["WPFWin11ISOStatusLog"].Height = 300
# Notify via the status log # Notify via the status log
$dirName = $existingWorkDir.Name $dirName = $existingWorkDir.Name
$modified = $existingWorkDir.LastWriteTime.ToString("yyyy-MM-dd HH:mm") $modified = $existingWorkDir.LastWriteTime.ToString("yyyy-MM-dd HH:mm")
Write-Win11ISOLog "Existing working directory found: $($existingWorkDir.FullName)" Write-Win11ISOLog "Existing working directory found: $($existingWorkDir.FullName)"
Write-Win11ISOLog "Last modified: $modified Skipping Steps 1-3 and resuming at Step 4." Write-Win11ISOLog "Last modified: $modified - Skipping Steps 1-3 and resuming at Step 4."
Write-Win11ISOLog "Click 'Clean & Reset' if you want to start over with a new ISO." Write-Win11ISOLog "Click 'Clean & Reset' if you want to start over with a new ISO."
[System.Windows.MessageBox]::Show( [System.Windows.MessageBox]::Show(
@@ -498,6 +500,8 @@ function Invoke-WinUtilISOCleanAndReset {
.SYNOPSIS .SYNOPSIS
Deletes the temporary working directory created during ISO modification Deletes the temporary working directory created during ISO modification
and resets the entire ISO UI back to its initial state (Step 1 only). and resets the entire ISO UI back to its initial state (Step 1 only).
Deletion runs in a background runspace so the UI stays responsive and
progress is reported to the user.
#> #>
$workDir = $sync["Win11ISOWorkDir"] $workDir = $sync["Win11ISOWorkDir"]
@@ -507,37 +511,126 @@ function Invoke-WinUtilISOCleanAndReset {
"This will delete the temporary working directory:`n`n$workDir`n`nAnd reset the interface back to the start.`n`nContinue?", "This will delete the temporary working directory:`n`n$workDir`n`nAnd reset the interface back to the start.`n`nContinue?",
"Clean & Reset", "YesNo", "Warning") "Clean & Reset", "YesNo", "Warning")
if ($confirm -ne "Yes") { return } if ($confirm -ne "Yes") { return }
try {
Write-Win11ISOLog "Deleting temp directory: $workDir"
Remove-Item -Path $workDir -Recurse -Force -ErrorAction Stop
Write-Win11ISOLog "Temp directory deleted."
} catch {
Write-Win11ISOLog "WARNING: could not fully delete temp directory: $_"
}
} }
# Clear all stored ISO state # Disable button so it cannot be clicked twice
$sync["Win11ISOWorkDir"] = $null $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $false
$sync["Win11ISOContentsDir"] = $null
$sync["Win11ISOImagePath"] = $null
$sync["Win11ISODriveLetter"] = $null
$sync["Win11ISOWimPath"] = $null
$sync["Win11ISOImageInfo"] = $null
$sync["Win11ISOUSBDisks"] = $null
# Reset the UI to the initial state $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$sync["WPFWin11ISOPath"].Text = "No ISO selected..." $runspace.ApartmentState = "STA"
$sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed" $runspace.ThreadOptions = "ReuseThread"
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed" $runspace.Open()
$sync["WPFWin11ISOOptionUSB"].Visibility = "Collapsed" $runspace.SessionStateProxy.SetVariable("sync", $sync)
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed" $runspace.SessionStateProxy.SetVariable("workDir", $workDir)
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed" $script = [Management.Automation.PowerShell]::Create()
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible" $script.Runspace = $runspace
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin." $script.AddScript({
$sync["WPFWin11ISOStatusLog"].Height = 140
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true function Log($msg) {
$ts = (Get-Date).ToString("HH:mm:ss")
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg"
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
})
}
function SetProgress($label, $pct) {
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync.progressBarTextBlock.Text = $label
$sync.progressBarTextBlock.ToolTip = $label
$sync.ProgressBar.Value = [Math]::Max($pct, 5)
})
}
try {
if ($workDir -and (Test-Path $workDir)) {
Log "Scanning files to delete in: $workDir"
SetProgress "Scanning files..." 5
$allItems = @(Get-ChildItem -Path $workDir -Recurse -Force -ErrorAction SilentlyContinue)
$total = $allItems.Count
$deleted = 0
Log "Found $total items to delete."
# Delete files first, then directories (deepest first)
$files = $allItems | Where-Object { -not $_.PSIsContainer }
$dirs = $allItems | Where-Object { $_.PSIsContainer } |
Sort-Object { $_.FullName.Length } -Descending
foreach ($f in $files) {
try { Remove-Item -Path $f.FullName -Force -ErrorAction Stop } catch {}
$deleted++
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
SetProgress "Deleting files... ($deleted / $total)" $pct
}
foreach ($d in $dirs) {
try { Remove-Item -Path $d.FullName -Force -Recurse -ErrorAction Stop } catch {}
$deleted++
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
SetProgress "Removing directories... ($deleted / $total)" $pct
}
# Remove the root work directory itself
try { Remove-Item -Path $workDir -Force -Recurse -ErrorAction Stop } catch {}
if (Test-Path $workDir) {
Log "WARNING: some items could not be deleted in $workDir"
} else {
Log "Temp directory deleted successfully."
}
} else {
Log "No temp directory found — resetting UI."
}
SetProgress "Resetting UI..." 95
Log "Resetting interface..."
# ── Full UI reset on the dispatcher thread ──────────────────────
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
# Clear stored state
$sync["Win11ISOWorkDir"] = $null
$sync["Win11ISOContentsDir"] = $null
$sync["Win11ISOImagePath"] = $null
$sync["Win11ISODriveLetter"] = $null
$sync["Win11ISOWimPath"] = $null
$sync["Win11ISOImageInfo"] = $null
$sync["Win11ISOUSBDisks"] = $null
# Reset UI elements
$sync["WPFWin11ISOPath"].Text = "No ISO selected..."
$sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed"
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
$sync["WPFWin11ISOOptionUSB"].Visibility = "Collapsed"
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed"
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
$sync.progressBarTextBlock.Text = ""
$sync.progressBarTextBlock.ToolTip = ""
$sync.ProgressBar.Value = 0
$sync["WPFWin11ISOStatusLog"].Height = 140
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin."
})
}
catch {
Log "ERROR during Clean & Reset: $_"
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync.progressBarTextBlock.Text = ""
$sync.progressBarTextBlock.ToolTip = ""
$sync.ProgressBar.Value = 0
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
})
}
}) | Out-Null
$script.BeginInvoke() | Out-Null
} }
function Invoke-WinUtilISOExport { function Invoke-WinUtilISOExport {

View File

@@ -1377,8 +1377,7 @@
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<!-- STEP 1 : Select Windows 11 ISO --> <!-- STEP 1 : Select Windows 11 ISO -->
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<Border Grid.Row="0" Name="WPFWin11ISOSelectSection" Style="{StaticResource BorderStyle}" HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}"> <Grid Grid.Row="0" Name="WPFWin11ISOSelectSection" Margin="5" HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
<Grid Margin="5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@@ -1464,18 +1463,16 @@
Height="{DynamicResource ButtonHeight}"/> Height="{DynamicResource ButtonHeight}"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>
</Border>
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<!-- STEP 2 : Mount & Verify ISO --> <!-- STEP 2 : Mount & Verify ISO -->
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<Border Grid.Row="1" <Grid Grid.Row="1"
Name="WPFWin11ISOMountSection" Name="WPFWin11ISOMountSection"
Style="{StaticResource BorderStyle}" Margin="5"
Visibility="Collapsed" Visibility="Collapsed"
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}"> HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
<Grid Margin="5">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@@ -1529,18 +1526,16 @@
Margin="0,0,0,0"/> Margin="0,0,0,0"/>
</StackPanel> </StackPanel>
</Border> </Border>
</Grid> </Grid>
</Border>
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<!-- STEP 3 : Modify install.wim --> <!-- STEP 3 : Modify install.wim -->
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<Border Grid.Row="2" <StackPanel Grid.Row="2"
Name="WPFWin11ISOModifySection" Name="WPFWin11ISOModifySection"
Style="{StaticResource BorderStyle}" Margin="5"
Visibility="Collapsed" Visibility="Collapsed"
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}"> HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
<StackPanel Margin="5">
<TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold" <TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold"
Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,8"> Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,8">
Step 3 - Modify install.wim Step 3 - Modify install.wim
@@ -1558,18 +1553,16 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
Width="Auto" Padding="12,0" Width="Auto" Padding="12,0"
Height="{DynamicResource ButtonHeight}"/> Height="{DynamicResource ButtonHeight}"/>
</StackPanel> </StackPanel>
</Border>
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<!-- STEP 4 : Output Options --> <!-- STEP 4 : Output Options -->
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<Border Grid.Row="3" <StackPanel Grid.Row="3"
Name="WPFWin11ISOOutputSection" Name="WPFWin11ISOOutputSection"
Style="{StaticResource BorderStyle}" Margin="5"
Visibility="Collapsed" Visibility="Collapsed"
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}"> HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
<StackPanel Margin="5">
<!-- Header row: title + Clean & Reset button --> <!-- Header row: title + Clean & Reset button -->
<Grid Margin="0,0,0,12"> <Grid Margin="0,0,0,12">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -1654,14 +1647,12 @@
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>
</Border>
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<!-- Status / Log Output --> <!-- Status / Log Output -->
<!-- ═══════════════════════════════════════════════════════════ --> <!-- ═══════════════════════════════════════════════════════════ -->
<Border Grid.Row="4" Style="{StaticResource BorderStyle}"> <StackPanel Grid.Row="4" Margin="5">
<StackPanel>
<TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold" <TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold"
Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,6"> Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,6">
Status Log Status Log
@@ -1677,7 +1668,6 @@
BorderThickness="1" BorderThickness="1"
Text="Ready. Please select a Windows 11 ISO to begin."/> Text="Ready. Please select a Windows 11 ISO to begin."/>
</StackPanel> </StackPanel>
</Border>
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>