From 1032d3d5aa503d65fdafc8f4aec12424df86d2ed Mon Sep 17 00:00:00 2001 From: MyDrift Date: Thu, 25 Jul 2024 23:19:45 +0200 Subject: [PATCH] Taskbaritem > Progressbar / Overlay icon / description / asset mgmt (#2309) * Add Progress bar to some stuff https://learn.microsoft.com/en-us/dotnet/api/system.windows.shell.taskbariteminfo?view=windowsdesktop-8.0 * add function to manage taskbar item changed from manually setting the taskbar overlay, progressvalue and progress state to setting them through a function * add description feature * use Dispatcher.Invoke * restructure, fix, additions * fix merge conflicts * add check to progresses * remove progress from wiget & choco install * fix * polish * fix * Update functions/private/Set-WinUtilTaskbarItem.ps1 Co-authored-by: Mr.k * fix syntax * Update functions/private/Set-WinUtilTaskbarItem.ps1 Co-authored-by: Mr.k * rework - add overlay presets - rework image saving & converting - removed popup after uninstalling applications * fix description of function * undo winutil * remove check.png * Update functions/private/Set-WinUtilTaskbarItem.ps1 Co-authored-by: Mr.k * Update functions/private/Set-WinUtilTaskbarItem.ps1 Co-authored-by: Mr.k * rework assets directory & its usage * fixes - ability to set no overlay added - added relative path to winutildir * hotfix * last fixes * add comment * remove trailing whitespaces THX to Mr.K :) * renamed checkmark & added warning * last fixes remove bitmap remove unneeded "| out-null" * hotfix for new commit --------- Co-authored-by: Mr.k --- .../private/Install-WinUtilProgramChoco.ps1 | 13 ++- .../private/Install-WinUtilProgramWinget.ps1 | 10 +++ functions/private/Install-WinUtilWinget.ps1 | 2 + .../private/Invoke-WinUtilFeatureInstall.ps1 | 8 ++ functions/private/Set-WinUtilTaskbarItem.ps1 | 86 +++++++++++++++++++ functions/public/Invoke-WPFFeatureInstall.ps1 | 8 +- functions/public/Invoke-WPFGetInstalled.ps1 | 2 + functions/public/Invoke-WPFGetIso.ps1 | 7 ++ functions/public/Invoke-WPFInstall.ps1 | 9 +- functions/public/Invoke-WPFInstallUpgrade.ps1 | 2 + functions/public/Invoke-WPFMicrowin.ps1 | 10 +++ functions/public/Invoke-WPFShortcut.ps1 | 18 ++-- functions/public/Invoke-WPFUnInstall.ps1 | 14 +-- functions/public/Invoke-WPFtweaksbutton.ps1 | 7 ++ functions/public/Invoke-WPFundoall.ps1 | 9 ++ scripts/main.ps1 | 72 +++++++++------- 16 files changed, 225 insertions(+), 52 deletions(-) create mode 100644 functions/private/Set-WinUtilTaskbarItem.ps1 diff --git a/functions/private/Install-WinUtilProgramChoco.ps1 b/functions/private/Install-WinUtilProgramChoco.ps1 index 43e42d79..029398f5 100644 --- a/functions/private/Install-WinUtilProgramChoco.ps1 +++ b/functions/private/Install-WinUtilProgramChoco.ps1 @@ -54,12 +54,18 @@ function Install-WinUtilProgramChoco { } if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)){ Write-Host "$($Program.choco) installed successfully using Chocolatey." + $X++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) }) continue } else { Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)." + $X++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) } } catch { Write-Host "Failed to install $($Program.choco) due to an error: $_" + $X++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) } } @@ -71,15 +77,20 @@ function Install-WinUtilProgramChoco { $chocoUninstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "uninstall $($Program.choco) -y" -Wait -PassThru).ExitCode if($chocoUninstallStatus -eq 0){ Write-Host "$($Program.choco) uninstalled successfully using Chocolatey." + $x++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) }) continue } else { Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)." + $x++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) } } catch { Write-Host "Failed to uninstall $($Program.choco) due to an error: $_" + $x++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) } } - $x++ } Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed diff --git a/functions/private/Install-WinUtilProgramWinget.ps1 b/functions/private/Install-WinUtilProgramWinget.ps1 index fc854eca..81114e2f 100644 --- a/functions/private/Install-WinUtilProgramWinget.ps1 +++ b/functions/private/Install-WinUtilProgramWinget.ps1 @@ -43,20 +43,24 @@ Function Install-WinUtilProgramWinget { $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode if($status -eq 0) { Write-Host "$($Program.winget) installed successfully." + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } if ($status -eq -1978335189) { Write-Host "$($Program.winget) No applicable update found" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } Write-Host "Attempt with User scope" $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode if($status -eq 0) { Write-Host "$($Program.winget) installed successfully with User scope." + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } if ($status -eq -1978335189) { Write-Host "$($Program.winget) No applicable update found" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } Write-Host "Attempt with User prompt" @@ -71,15 +75,18 @@ Function Install-WinUtilProgramWinget { } if($status -eq 0) { Write-Host "$($Program.winget) installed successfully with User prompt." + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } if ($status -eq -1978335189) { Write-Host "$($Program.winget) No applicable update found" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) continue } } catch { Write-Host "Failed to install $($Program.winget). With winget" $failedPackages += $Program + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) } } elseif($manage -eq "Uninstalling") { @@ -88,6 +95,7 @@ Function Install-WinUtilProgramWinget { $status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode if($status -ne 0) { Write-Host "Failed to uninstall $($Program.winget)." + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) } else { Write-Host "$($Program.winget) uninstalled successfully." $failedPackages += $Program @@ -95,7 +103,9 @@ Function Install-WinUtilProgramWinget { } catch { Write-Host "Failed to uninstall $($Program.winget) due to an error: $_" $failedPackages += $Program + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) } + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) } else { throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage" diff --git a/functions/private/Install-WinUtilWinget.ps1 b/functions/private/Install-WinUtilWinget.ps1 index b22fcd28..881a138f 100644 --- a/functions/private/Install-WinUtilWinget.ps1 +++ b/functions/private/Install-WinUtilWinget.ps1 @@ -19,6 +19,7 @@ function Install-WinUtilWinget { Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red } + # Gets the computer's information if ($null -eq $sync.ComputerInfo){ $ComputerInfo = Get-ComputerInfo -ErrorAction Stop @@ -63,4 +64,5 @@ function Install-WinUtilWinget { throw [WingetFailedInstall]::new('Failed to install!') } } + } diff --git a/functions/private/Invoke-WinUtilFeatureInstall.ps1 b/functions/private/Invoke-WinUtilFeatureInstall.ps1 index 8fc6ee2c..4b3a0f65 100644 --- a/functions/private/Invoke-WinUtilFeatureInstall.ps1 +++ b/functions/private/Invoke-WinUtilFeatureInstall.ps1 @@ -10,6 +10,8 @@ function Invoke-WinUtilFeatureInstall { $CheckBox ) + $x = 0 + $CheckBox | ForEach-Object { if($sync.configs.feature.$psitem.feature){ Foreach( $feature in $sync.configs.feature.$psitem.feature ){ @@ -20,9 +22,11 @@ function Invoke-WinUtilFeatureInstall { Catch{ if ($psitem.Exception.Message -like "*requires elevation*"){ Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) } else{ + Write-Warning "Unable to Install $feature due to unhandled exception" Write-Warning $psitem.Exception.StackTrace } @@ -40,14 +44,18 @@ function Invoke-WinUtilFeatureInstall { Catch{ if ($psitem.Exception.Message -like "*requires elevation*"){ Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) } else{ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) Write-Warning "Unable to Install $feature due to unhandled exception" Write-Warning $psitem.Exception.StackTrace } } } } + $X++ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) }) } } diff --git a/functions/private/Set-WinUtilTaskbarItem.ps1 b/functions/private/Set-WinUtilTaskbarItem.ps1 new file mode 100644 index 00000000..7f290fac --- /dev/null +++ b/functions/private/Set-WinUtilTaskbarItem.ps1 @@ -0,0 +1,86 @@ +function Set-WinUtilTaskbaritem { + <# + + .SYNOPSIS + Modifies the Taskbaritem of the WPF Form + + .PARAMETER value + Value can be between 0 and 1, 0 being no progress done yet and 1 being fully completed + Value does not affect item without setting the state to 'Normal', 'Error' or 'Paused' + Set-WinUtilTaskbaritem -value 0.5 + + .PARAMETER state + State can be 'None' > No progress, 'Indeterminate' > inf. loading gray, 'Normal' > Gray, 'Error' > Red, 'Paused' > Yellow + no value needed: + - Set-WinUtilTaskbaritem -state "None" + - Set-WinUtilTaskbaritem -state "Indeterminate" + value needed: + - Set-WinUtilTaskbaritem -state "Error" + - Set-WinUtilTaskbaritem -state "Normal" + - Set-WinUtilTaskbaritem -state "Paused" + + .PARAMETER overlay + Overlay icon to display on the taskbar item, there are the presets 'None', 'logo' and 'checkmark' or you can specify a path/link to an image file. + CTT logo preset: + - Set-WinUtilTaskbaritem -overlay "logo" + Checkmark preset: + - Set-WinUtilTaskbaritem -overlay "checkmark" + Warning preset: + - Set-WinUtilTaskbaritem -overlay "warning" + No overlay: + - Set-WinUtilTaskbaritem -overlay "None" + Custom icon (needs to be supported by WPF): + - Set-WinUtilTaskbaritem -overlay "C:\path\to\icon.png" + + .PARAMETER description + Description to display on the taskbar item preview + Set-WinUtilTaskbaritem -description "This is a description" + #> + param ( + [string]$state, + [double]$value, + [string]$overlay, + [string]$description + ) + + if ($value) { + $sync["Form"].taskbarItemInfo.ProgressValue = $value + } + + if ($state) { + switch ($state) { + 'None' { $sync["Form"].taskbarItemInfo.ProgressState = "None" } + 'Indeterminate' { $sync["Form"].taskbarItemInfo.ProgressState = "Indeterminate" } + 'Normal' { $sync["Form"].taskbarItemInfo.ProgressState = "Normal" } + 'Error' { $sync["Form"].taskbarItemInfo.ProgressState = "Error" } + 'Paused' { $sync["Form"].taskbarItemInfo.ProgressState = "Paused" } + default { throw "[Set-WinUtilTaskbarItem] Invalid state" } + } + } + + if ($overlay) { + switch ($overlay) { + 'logo' { + $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png" + } + 'checkmark' { + $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png" + } + 'warning' { + $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png" + } + 'None' { + $sync["Form"].taskbarItemInfo.Overlay = $null + } + default { + if (Test-Path $overlay) { + $sync["Form"].taskbarItemInfo.Overlay = $overlay + } + } + } + } + + if ($description) { + $sync["Form"].taskbarItemInfo.Description = $description + } +} \ No newline at end of file diff --git a/functions/public/Invoke-WPFFeatureInstall.ps1 b/functions/public/Invoke-WPFFeatureInstall.ps1 index 180100b2..57cbc38e 100644 --- a/functions/public/Invoke-WPFFeatureInstall.ps1 +++ b/functions/public/Invoke-WPFFeatureInstall.ps1 @@ -16,12 +16,18 @@ function Invoke-WPFFeatureInstall { Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock { param($Features, $DebugPreference) - $sync.ProcessRunning = $true + if ($Features.count -eq 1){ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) + } else { + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) + } Invoke-WinUtilFeatureInstall $Features $sync.ProcessRunning = $false + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) + Write-Host "===================================" Write-Host "--- Features are Installed ---" Write-Host "--- A Reboot may be required ---" diff --git a/functions/public/Invoke-WPFGetInstalled.ps1 b/functions/public/Invoke-WPFGetInstalled.ps1 index 18b690fd..9ef1c3ac 100644 --- a/functions/public/Invoke-WPFGetInstalled.ps1 +++ b/functions/public/Invoke-WPFGetInstalled.ps1 @@ -24,6 +24,7 @@ function Invoke-WPFGetInstalled { param($checkbox, $DebugPreference) $sync.ProcessRunning = $true + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" }) if($checkbox -eq "winget"){ Write-Host "Getting Installed Programs..." @@ -42,5 +43,6 @@ function Invoke-WPFGetInstalled { Write-Host "Done..." $sync.ProcessRunning = $false + $sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" }) } } diff --git a/functions/public/Invoke-WPFGetIso.ps1 b/functions/public/Invoke-WPFGetIso.ps1 index 6e97834c..01390dc1 100644 --- a/functions/public/Invoke-WPFGetIso.ps1 +++ b/functions/public/Invoke-WPFGetIso.ps1 @@ -16,6 +16,7 @@ function Invoke-WPFGetIso { $sync.BusyText.Text="N Busy" + Write-Host " _ __ __ _ " Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ " Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ " @@ -88,6 +89,8 @@ function Invoke-WPFGetIso { return } + Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo" + # Detect the file size of the ISO and compare it with the free space of the system drive $isoSize = (Get-Item -Path $filePath).Length Write-Debug "Size of ISO file: $($isoSize) bytes" @@ -104,6 +107,7 @@ function Invoke-WPFGetIso { { # It's critical and we can't continue. Output an error Write-Host "You don't have enough space for this operation. You need at least $([Math]::Round(($isoSize / ([Math]::Pow(1024, 2))) * 2, 2)) MB of free space to copy the ISO files to a temp directory and to be able to perform additional operations." + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } else @@ -122,6 +126,7 @@ function Invoke-WPFGetIso { Write-Error "Failed to mount the image. Error: $($_.Exception.Message)" Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system" Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd" + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } # storing off values in hidden fields for further steps @@ -199,6 +204,7 @@ function Invoke-WPFGetIso { $msg = "Neither install.wim nor install.esd exist in the image, this could happen if you use unofficial Windows images. Please don't use shady images from the internet, use only official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/" Write-Host $msg [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" throw } elseif ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf)) @@ -239,6 +245,7 @@ function Invoke-WPFGetIso { $sync.BusyMessage.Visibility="Hidden" $sync.ProcessRunning = $false + Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } diff --git a/functions/public/Invoke-WPFInstall.ps1 b/functions/public/Invoke-WPFInstall.ps1 index 0032f10f..b4b0cf21 100644 --- a/functions/public/Invoke-WPFInstall.ps1 +++ b/functions/public/Invoke-WPFInstall.ps1 @@ -20,8 +20,14 @@ function Invoke-WPFInstall { return } + Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock { param($PackagesToInstall, $DebugPreference) + if ($PackagesToInstall.count -eq 1){ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) + } else { + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) + } $packagesWinget, $packagesChoco = { $packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() @@ -52,13 +58,14 @@ function Invoke-WPFInstall { Write-Host "===========================================" Write-Host "-- Installs have finished ---" Write-Host "===========================================" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) } Catch { Write-Host "===========================================" Write-Host "Error: $_" Write-Host "===========================================" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }) } - Start-Sleep -Seconds 5 $sync.ProcessRunning = $False } } diff --git a/functions/public/Invoke-WPFInstallUpgrade.ps1 b/functions/public/Invoke-WPFInstallUpgrade.ps1 index a8e985bd..c62dfe1d 100644 --- a/functions/public/Invoke-WPFInstallUpgrade.ps1 +++ b/functions/public/Invoke-WPFInstallUpgrade.ps1 @@ -15,6 +15,8 @@ function Invoke-WPFInstallUpgrade { return } + # Set-WinUtilTaskbaritem -state "Indeterminate" + Update-WinUtilProgramWinget Write-Host "===========================================" diff --git a/functions/public/Invoke-WPFMicrowin.ps1 b/functions/public/Invoke-WPFMicrowin.ps1 index 1427f096..b54e2625 100644 --- a/functions/public/Invoke-WPFMicrowin.ps1 +++ b/functions/public/Invoke-WPFMicrowin.ps1 @@ -4,6 +4,7 @@ function Invoke-WPFMicrowin { Invoke MicroWin routines... #> + if($sync.ProcessRunning) { $msg = "GetIso process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) @@ -39,9 +40,12 @@ public class PowerManagement { if ($SaveDialog.FileName -eq "") { Write-Host "No file name for the target image was specified" + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } + Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo" + Write-Host "Target ISO location: $($SaveDialog.FileName)" $index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim() @@ -74,6 +78,7 @@ public class PowerManagement { $msg = "The export process has failed and MicroWin processing cannot continue" Write-Host "Failed to export the image" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } } @@ -87,6 +92,7 @@ public class PowerManagement { $dlg_msg = $msg + "`n`nIf you want more information, the version of the image selected is $($imgVersion)`n`nIf an image has been incorrectly marked as incompatible, report an issue to the developers." Write-Host $msg [System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation) + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } @@ -95,6 +101,7 @@ public class PowerManagement { if (-not $mountDirExists -or -not $scratchDirExists) { Write-Error "Required directories '$mountDirExists' '$scratchDirExists' and do not exist." + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } @@ -109,6 +116,7 @@ public class PowerManagement { else { Write-Host "Could not mount image. Exiting..." + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } @@ -378,6 +386,7 @@ public class PowerManagement { if (-not (Test-Path -Path "$mountDir\sources\install.wim")) { Write-Error "Something went wrong and '$mountDir\sources\install.wim' doesn't exist. Please report this bug to the devs" + Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" return } Write-Host "Windows image completed. Continuing with boot.wim." @@ -479,6 +488,7 @@ public class PowerManagement { #$msg = "Done. ISO image is located here: $env:temp\microwin.iso" $msg = "Done. ISO image is located here: $($SaveDialog.FileName)" Write-Host $msg + Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } else { Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed." diff --git a/functions/public/Invoke-WPFShortcut.ps1 b/functions/public/Invoke-WPFShortcut.ps1 index 048d3b7e..513ede95 100644 --- a/functions/public/Invoke-WPFShortcut.ps1 +++ b/functions/public/Invoke-WPFShortcut.ps1 @@ -17,8 +17,8 @@ function Invoke-WPFShortcut { [bool]$RunAsAdmin = $false ) - # add an a Custom Icon if it's available at "$env:TEMP\cttlogo.png", else don't add a Custom Icon. - $iconPath = $null + # Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon. + Switch ($ShortcutToAdd) { "WinUtil" { # Use Powershell 7 if installed and fallback to PS5 if not @@ -33,12 +33,6 @@ function Invoke-WPFShortcut { $DestinationName = "WinUtil.lnk" - Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile "$env:TEMP\cttlogo.png" - - if (Test-Path -Path "$env:TEMP\cttlogo.png") { - $iconPath = "$env:LOCALAPPDATA\winutil\cttlogo.ico" - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath - } } } @@ -58,10 +52,10 @@ function Invoke-WPFShortcut { # Prepare the Shortcut paramter $WshShell = New-Object -comObject WScript.Shell $Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName) - $Shortcut.TargetPath = $shell - $Shortcut.Arguments = $shellArgs - if ($null -ne $iconPath) { - $shortcut.IconLocation = $iconPath + $Shortcut.TargetPath = $SourceExe + $Shortcut.Arguments = $ArgumentsToSourceExe + if (Test-Path -Path $winutildir["logo.ico"]) { + $shortcut.IconLocation = $winutildir["logo.ico"] } # Save the Shortcut to disk diff --git a/functions/public/Invoke-WPFUnInstall.ps1 b/functions/public/Invoke-WPFUnInstall.ps1 index f3a9c64f..e0195ada 100644 --- a/functions/public/Invoke-WPFUnInstall.ps1 +++ b/functions/public/Invoke-WPFUnInstall.ps1 @@ -29,8 +29,14 @@ function Invoke-WPFUnInstall { if($confirm -eq "No"){return} + Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock { param($PackagesToInstall, $DebugPreference) + if ($PackagesToInstall.count -eq 1){ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) + } else { + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) + } $packagesWinget, $packagesChoco = { $packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() @@ -56,22 +62,20 @@ function Invoke-WPFUnInstall { Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling" } - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Uninstalls are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) Write-Host "===========================================" Write-Host "-- Uninstalls have finished ---" Write-Host "===========================================" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) } Catch { Write-Host "===========================================" Write-Host "Error: $_" Write-Host "===========================================" + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }) } $sync.ProcessRunning = $False + } } diff --git a/functions/public/Invoke-WPFtweaksbutton.ps1 b/functions/public/Invoke-WPFtweaksbutton.ps1 index 9eb60cf2..79bcfbbd 100644 --- a/functions/public/Invoke-WPFtweaksbutton.ps1 +++ b/functions/public/Invoke-WPFtweaksbutton.ps1 @@ -30,15 +30,22 @@ function Invoke-WPFtweaksbutton { $sync.ProcessRunning = $true + if ($Tweaks.count -eq 1){ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) + } else { + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) + } $cnt = 0 # Execute other selected tweaks foreach ($tweak in $Tweaks) { Write-Debug "This is a tweak to run $tweak count: $cnt" Invoke-WinUtilTweaks $tweak $cnt += 1 + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) } $sync.ProcessRunning = $false + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) Write-Host "=================================" Write-Host "-- Tweaks are Finished ---" Write-Host "=================================" diff --git a/functions/public/Invoke-WPFundoall.ps1 b/functions/public/Invoke-WPFundoall.ps1 index 9d961f6e..d706b815 100644 --- a/functions/public/Invoke-WPFundoall.ps1 +++ b/functions/public/Invoke-WPFundoall.ps1 @@ -24,12 +24,21 @@ function Invoke-WPFundoall { param($Tweaks, $DebugPreference) $sync.ProcessRunning = $true + if ($Tweaks.count -eq 1){ + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) + } else { + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) + } + $cnt = 0 Foreach ($tweak in $tweaks){ Invoke-WinUtilTweaks $tweak -undo $true + $cnt += 1 + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) } $sync.ProcessRunning = $false + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) Write-Host "==================================" Write-Host "--- Undo Tweaks are Finished ---" Write-Host "==================================" diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 0c83c54c..248bf605 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -154,6 +154,10 @@ Invoke-WPFRunspace -ScriptBlock { # Print the logo Invoke-WPFFormVariables +# Progress bar in taskbaritem > Set-WinUtilProgressbar +$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo +Set-WinUtilTaskbaritem -state "None" + # Set the titlebar $sync["Form"].title = $sync["Form"].title + " " + $sync.version # Set the commands that will run when the form is closed @@ -288,38 +292,6 @@ Add-Type @" } } - - # Using a TaskbarItem Overlay until someone figures out how to replace the icon correctly - - # URL of the image - $imageUrl = "https://christitus.com/images/logo-full.png" - - # Download the image - $imagePath = "$env:TEMP\logo-full.png" - Invoke-WebRequest -Uri $imageUrl -OutFile $imagePath - - # Read the image file as a byte array - $imageBytes = [System.IO.File]::ReadAllBytes($imagePath) - - # Convert the byte array to a Base64 string - $base64String = [System.Convert]::ToBase64String($imageBytes) - - # Create a streaming image by streaming the base64 string to a bitmap streamsource - $bitmap = New-Object System.Windows.Media.Imaging.BitmapImage - $bitmap.BeginInit() - $bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64String) - $bitmap.EndInit() - $bitmap.Freeze() - - # Ensure TaskbarItemInfo is created if not already - if (-not $sync["Form"].TaskbarItemInfo) { - $sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo - } - - # Set the overlay icon for the taskbar - $sync["Form"].TaskbarItemInfo.Overlay = $bitmap - - $rect = New-Object RECT [Window]::GetWindowRect($windowHandle, [ref]$rect) $width = $rect.Right - $rect.Left @@ -458,6 +430,42 @@ $sync["SearchBar"].Add_TextChanged({ $label.Visibility = "Collapsed"} }) +# Initialize the hashtable +$winutildir = @{} + +# Set the path for the winutil directory +$winutildir["path"] = "$env:LOCALAPPDATA\winutil\" +if (-NOT (Test-Path -Path $winutildir["path"])) { + New-Item -Path $winutildir["path"] -ItemType Directory +} + +# Set the path for the logo and checkmark images +$winutildir["logo.png"] = $winutildir["path"] + "cttlogo.png" +$winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico" +if (-NOT (Test-Path -Path $winutildir["logo.png"])) { + Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile $winutildir["logo.png"] +} + +if (-NOT (Test-Path -Path $winutildir["logo.ico"])) { + ConvertTo-Icon -bitmapPath $winutildir["logo.png"] -iconPath $winutildir["logo.ico"] +} + +$winutildir["checkmark.png"] = $winutildir["path"] + "checkmark.png" +$winutildir["warning.png"] = $winutildir["path"] + "warning.png" +if (-NOT (Test-Path -Path $winutildir["checkmark.png"])) { + Invoke-WebRequest -Uri "https://christitus.com/images/checkmark.png" -OutFile $winutildir["checkmark.png"] +} +if (-NOT (Test-Path -Path $winutildir["warning.png"])) { + Invoke-WebRequest -Uri "https://christitus.com/images/warning.png" -OutFile $winutildir["warning.png"] +} + + +Set-WinUtilTaskbaritem -overlay "logo" + +$sync["Form"].Add_Activated({ + Set-WinUtilTaskbaritem -overlay "logo" +}) + # Define event handler for button click $sync["SettingsButton"].Add_Click({ Write-Debug "SettingsButton clicked"