mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 09:31:15 +10:00
Replace install progress overlay with shared indicator (#4844)
* Use shared progress for app workflows * Remove legacy install progress overlay * Document shared app progress indicator * Address progress review feedback * Track all Win11 ISO progress * Restore Win11 Creator work on relaunch
This commit is contained in:
@@ -46,9 +46,6 @@ BeforeAll {
|
||||
function Invoke-WPFUIThread {
|
||||
param([scriptblock]$ScriptBlock)
|
||||
}
|
||||
function Set-WinUtilProgressBar {
|
||||
param($Label, $Percent)
|
||||
}
|
||||
function Set-WinUtilTweaksProgressIndicator {
|
||||
param($Visible, $Label, $Percent)
|
||||
}
|
||||
@@ -235,7 +232,6 @@ Describe "Get installed AppX selection" {
|
||||
WPFAppxMissing = [pscustomobject]@{ IsChecked = $false }
|
||||
})
|
||||
|
||||
Mock Set-WinUtilProgressBar { }
|
||||
Mock Set-WinUtilTweaksProgressIndicator { }
|
||||
Mock Get-WinUtilInstalledAPPX { @("Example.Package") }
|
||||
Mock Invoke-WPFAppxInstall { }
|
||||
|
||||
@@ -18,10 +18,9 @@ BeforeAll {
|
||||
function Get-WinUtilSelectedPackages {
|
||||
param($PackageList, [string]$Preference)
|
||||
}
|
||||
function Show-WPFInstallAppBusy {
|
||||
param($text)
|
||||
function Set-WinUtilTweaksProgressIndicator {
|
||||
param($Visible, $Label, $Percent)
|
||||
}
|
||||
function Hide-WPFInstallAppBusy { }
|
||||
function Install-WinUtilWinget { }
|
||||
function Install-WinUtilChoco { }
|
||||
function Install-WinUtilProgramWinget {
|
||||
@@ -74,6 +73,9 @@ BeforeAll {
|
||||
preferences = [pscustomobject]@{
|
||||
packagemanager = "Winget"
|
||||
}
|
||||
Form = [pscustomobject]@{
|
||||
Dispatcher = [pscustomobject]@{}
|
||||
}
|
||||
configs = @{
|
||||
applicationsHashtable = $applications
|
||||
}
|
||||
@@ -187,8 +189,7 @@ Describe "Invoke-WPFInstall runspace body" {
|
||||
Mock Get-WinUtilSelectedPackages {
|
||||
New-WinUtilPackageSplit -Winget @("Git.Git") -Choco @("vlc")
|
||||
}
|
||||
Mock Show-WPFInstallAppBusy { }
|
||||
Mock Hide-WPFInstallAppBusy { }
|
||||
Mock Set-WinUtilTweaksProgressIndicator { }
|
||||
Mock Install-WinUtilWinget { }
|
||||
Mock Install-WinUtilChoco { }
|
||||
Mock Install-WinUtilProgramWinget { }
|
||||
@@ -212,8 +213,17 @@ Describe "Invoke-WPFInstall runspace body" {
|
||||
Should -Invoke -CommandName Get-WinUtilSelectedPackages -Times 1 -Exactly -ParameterFilter {
|
||||
@($PackageList).Count -eq 1 -and $Preference -eq "Winget"
|
||||
}
|
||||
Should -Invoke -CommandName Show-WPFInstallAppBusy -Times 1 -Exactly -ParameterFilter {
|
||||
$text -eq "Installing apps..."
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Preparing app install (0/2)" -and $Percent -eq 0
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Installed Git.Git (1/2)" -and $Percent -eq 50
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Installed Chocolatey packages (2/2)" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "App install finished" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Install-WinUtilWinget -Times 1 -Exactly
|
||||
Should -Invoke -CommandName Install-WinUtilProgramWinget -Times 1 -Exactly -ParameterFilter {
|
||||
@@ -223,21 +233,34 @@ Describe "Invoke-WPFInstall runspace body" {
|
||||
Should -Invoke -CommandName Install-WinUtilProgramChoco -Times 1 -Exactly -ParameterFilter {
|
||||
$Action -eq "Install" -and @($Programs)[0] -eq "vlc"
|
||||
}
|
||||
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $false*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $true*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"*'
|
||||
}
|
||||
$script:sync.ProcessRunning | Should -BeFalse
|
||||
}
|
||||
|
||||
It "hides the busy overlay, sets taskbar error state, and clears ProcessRunning on failure" {
|
||||
It "shows failure progress, sets taskbar error state, and clears ProcessRunning on failure" {
|
||||
Mock Install-WinUtilProgramWinget { throw "winget failed" }
|
||||
|
||||
Invoke-WPFInstall
|
||||
|
||||
& $script:capturedInstallScriptBlock -PackagesToInstall @($script:package) -ManagerPreference "Winget"
|
||||
|
||||
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "App install failed" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $false*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $true*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*Set-WinUtilTaskbaritem -state "Error" -overlay "warning"*'
|
||||
}
|
||||
@@ -345,8 +368,7 @@ Describe "Invoke-WPFUnInstall runspace body" {
|
||||
Mock Get-WinUtilSelectedPackages {
|
||||
New-WinUtilPackageSplit -Winget @("Git.Git") -Choco @("vlc")
|
||||
}
|
||||
Mock Show-WPFInstallAppBusy { }
|
||||
Mock Hide-WPFInstallAppBusy { }
|
||||
Mock Set-WinUtilTweaksProgressIndicator { }
|
||||
Mock Install-WinUtilProgramWinget { }
|
||||
Mock Install-WinUtilProgramChoco { }
|
||||
Mock Invoke-WPFUIThread { }
|
||||
@@ -369,8 +391,17 @@ Describe "Invoke-WPFUnInstall runspace body" {
|
||||
Should -Invoke -CommandName Get-WinUtilSelectedPackages -Times 1 -Exactly -ParameterFilter {
|
||||
@($PackageList).Count -eq 1 -and $Preference -eq "Winget"
|
||||
}
|
||||
Should -Invoke -CommandName Show-WPFInstallAppBusy -Times 1 -Exactly -ParameterFilter {
|
||||
$text -eq "Uninstalling apps..."
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Preparing app uninstall (0/2)" -and $Percent -eq 0
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Uninstalled Git.Git (1/2)" -and $Percent -eq 50
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "Uninstalled Chocolatey packages (2/2)" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "App uninstall finished" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Install-WinUtilProgramWinget -Times 1 -Exactly -ParameterFilter {
|
||||
$Action -eq "Uninstall" -and @($Programs)[0] -eq "Git.Git"
|
||||
@@ -378,21 +409,34 @@ Describe "Invoke-WPFUnInstall runspace body" {
|
||||
Should -Invoke -CommandName Install-WinUtilProgramChoco -Times 1 -Exactly -ParameterFilter {
|
||||
$Action -eq "Uninstall" -and @($Programs)[0] -eq "vlc"
|
||||
}
|
||||
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $false*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $true*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"*'
|
||||
}
|
||||
$script:sync.ProcessRunning | Should -BeFalse
|
||||
}
|
||||
|
||||
It "hides the busy overlay, sets taskbar error state, and clears ProcessRunning on failure" {
|
||||
It "shows failure progress, sets taskbar error state, and clears ProcessRunning on failure" {
|
||||
Mock Install-WinUtilProgramWinget { throw "winget failed" }
|
||||
|
||||
Invoke-WPFUnInstall -PackagesToUninstall @($script:package)
|
||||
|
||||
& $script:capturedUninstallScriptBlock -PackagesToUninstall @($script:package) -ManagerPreference "Winget"
|
||||
|
||||
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
|
||||
Should -Invoke -CommandName Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $true -and $Label -eq "App uninstall failed" -and $Percent -eq 100
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $false*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*$sync.ItemsControl.IsEnabled = $true*'
|
||||
}
|
||||
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
|
||||
$ScriptBlock.ToString() -like '*Set-WinUtilTaskbaritem -state "Error" -overlay "warning"*'
|
||||
}
|
||||
|
||||
@@ -69,6 +69,23 @@ Describe "Initialize-WinUtilTabContent" {
|
||||
$targetGridName -eq "appxpanel" -and $columncount -eq 2
|
||||
}
|
||||
}
|
||||
|
||||
It "checks for existing Win11ISO work when the tab is initialized" {
|
||||
Add-Type -AssemblyName WindowsBase
|
||||
$dispatcher = [pscustomobject]@{}
|
||||
$dispatcher | Add-Member -MemberType ScriptMethod -Name BeginInvoke -Value {
|
||||
param($priority, $action)
|
||||
$action.Invoke()
|
||||
}
|
||||
$script:sync.Form = [pscustomobject]@{ Dispatcher = $dispatcher }
|
||||
Mock Invoke-WinUtilISOCheckExistingWork { }
|
||||
|
||||
Initialize-WinUtilTabContent -TabName "Win11ISO"
|
||||
Initialize-WinUtilTabContent -TabName "Win11ISO"
|
||||
|
||||
Should -Invoke -CommandName Invoke-WinUtilISOCheckExistingWork -Times 1 -Exactly
|
||||
$script:sync.InitializedTabs["Win11ISO"] | Should -BeTrue
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Startup lazy tab wiring" {
|
||||
|
||||
@@ -31,9 +31,6 @@ BeforeAll {
|
||||
function Invoke-WPFUIThread {
|
||||
param([scriptblock]$ScriptBlock)
|
||||
}
|
||||
function Set-WinUtilProgressBar {
|
||||
param($Label, $Percent)
|
||||
}
|
||||
function Set-WinUtilTweaksProgressIndicator {
|
||||
param($Visible, $Label, $Percent)
|
||||
}
|
||||
@@ -187,7 +184,6 @@ Describe "Invoke-WPFtweaksbutton" {
|
||||
Mock Invoke-WPFRunspace { [pscustomobject]@{ MockHandle = $true } }
|
||||
Mock Invoke-WinUtilTweaks { }
|
||||
Mock Invoke-WPFUIThread { }
|
||||
Mock Set-WinUtilProgressBar { }
|
||||
Mock Write-WinUtilLog { }
|
||||
Mock Write-Host { }
|
||||
}
|
||||
|
||||
@@ -65,10 +65,6 @@ namespace System.Windows.Controls
|
||||
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFButton.ps1")
|
||||
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFToggleAllCategories.ps1")
|
||||
|
||||
function Set-WinUtilProgressBar {
|
||||
param($Label, $Percent)
|
||||
}
|
||||
|
||||
function Set-WinUtilTweaksProgressIndicator {
|
||||
param($Visible, $Label, $Percent)
|
||||
}
|
||||
@@ -303,7 +299,6 @@ Describe "Invoke-WPFToggleAllCategories" {
|
||||
Describe "Invoke-WPFButton progress cleanup" {
|
||||
BeforeEach {
|
||||
New-WinUtilUiStateTestContext
|
||||
Mock Set-WinUtilProgressBar { }
|
||||
Mock Set-WinUtilTweaksProgressIndicator { }
|
||||
}
|
||||
|
||||
@@ -317,9 +312,6 @@ Describe "Invoke-WPFButton progress cleanup" {
|
||||
|
||||
Invoke-WPFButton -Button "WPFNoOp"
|
||||
|
||||
Should -Invoke Set-WinUtilProgressBar -Times 1 -Exactly -ParameterFilter {
|
||||
$Label -eq "" -and $Percent -eq 0
|
||||
}
|
||||
Should -Invoke Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
|
||||
$Visible -eq $false
|
||||
}
|
||||
@@ -330,7 +322,15 @@ Describe "Invoke-WPFButton progress cleanup" {
|
||||
|
||||
Invoke-WPFButton -Button "WPFNoOp"
|
||||
|
||||
Should -Not -Invoke Set-WinUtilProgressBar
|
||||
Should -Not -Invoke Set-WinUtilTweaksProgressIndicator
|
||||
}
|
||||
|
||||
It "leaves progress visible while a Win11 ISO process is running" {
|
||||
$script:sync.ProcessRunning = $false
|
||||
$script:sync.Win11ISOProcessRunning = $true
|
||||
|
||||
Invoke-WPFButton -Button "WPFNoOp"
|
||||
|
||||
Should -Not -Invoke Set-WinUtilTweaksProgressIndicator
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ Describe "Win11 Creator setup media" {
|
||||
BeforeAll {
|
||||
$script:repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||
$script:isoWorkflowPath = Join-Path $script:repoRoot "functions\private\Invoke-WinUtilISO.ps1"
|
||||
$script:isoUsbWorkflowPath = Join-Path $script:repoRoot "functions\private\Invoke-WinUtilISOUSB.ps1"
|
||||
$script:isoScriptPath = Join-Path $script:repoRoot "functions\private\Invoke-WinUtilISOScript.ps1"
|
||||
$script:autoUnattendPath = Join-Path $script:repoRoot "tools\autounattend.xml"
|
||||
|
||||
@@ -36,6 +37,9 @@ Describe "Win11 Creator setup media" {
|
||||
}
|
||||
|
||||
$script:modifyFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Invoke-WinUtilISOModify"
|
||||
$script:cleanAndResetFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Invoke-WinUtilISOCleanAndReset"
|
||||
$script:exportFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Invoke-WinUtilISOExport"
|
||||
$script:writeUsbFunction = Get-WinUtilFunctionText -Path $script:isoUsbWorkflowPath -FunctionName "Invoke-WinUtilISOWriteUSB"
|
||||
$script:editionIdFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Get-WinUtilEditionIdFromName"
|
||||
$script:addDriversFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Add-DriversToImage"
|
||||
$script:answerFileChildElementFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Get-WinUtilISOScriptChildElement"
|
||||
@@ -81,6 +85,18 @@ Describe "Win11 Creator setup media" {
|
||||
$script:modifyFunction | Should -Not -Match ([regex]::Escape("Reusing existing temp directory"))
|
||||
}
|
||||
|
||||
It "tracks every background ISO workflow with the shared busy state" {
|
||||
foreach ($functionText in @(
|
||||
$script:modifyFunction,
|
||||
$script:cleanAndResetFunction,
|
||||
$script:exportFunction,
|
||||
$script:writeUsbFunction
|
||||
)) {
|
||||
$functionText | Should -Match ([regex]::Escape('$sync["Win11ISOProcessRunning"] = $true'))
|
||||
$functionText | Should -Match ([regex]::Escape('$sync["Win11ISOProcessRunning"] = $false'))
|
||||
}
|
||||
}
|
||||
|
||||
It "mounts the copied image file that was verified from the ISO" {
|
||||
foreach ($expectedText in @(
|
||||
'$sourceImageFileName = Split-Path $wimPath -Leaf',
|
||||
|
||||
@@ -432,20 +432,15 @@ Describe "XAML and sync wiring" {
|
||||
"InitializedTabs",
|
||||
"RenderedAssetCache",
|
||||
"ToggleStatusCache",
|
||||
"InstallAppAreaBorder",
|
||||
"InstallAppAreaScrollViewer",
|
||||
"InstallAppAreaOverlay",
|
||||
"InstallAppAreaOverlayText",
|
||||
"InstallAppRenderQueue",
|
||||
"InstallAppEntriesRendered",
|
||||
"ProgressBar",
|
||||
"progressBarTextBlock",
|
||||
"FontScaleFactor",
|
||||
"Win11ISOImageInfo",
|
||||
"Win11ISODriveLetter",
|
||||
"Win11ISOWimPath",
|
||||
"Win11ISOImagePath",
|
||||
"Win11ISOModifying",
|
||||
"Win11ISOProcessRunning",
|
||||
"Win11ISOWorkDir",
|
||||
"Win11ISOContentsDir",
|
||||
"Win11ISOUSBDisks"
|
||||
|
||||
Reference in New Issue
Block a user