Write-Host @" CCCCCCCCCCCCCTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT CCC::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T CC:::::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T C:::::CCCCCCCC::::CT:::::TT:::::::TT:::::TT:::::TT:::::::TT:::::T C:::::C CCCCCCTTTTTT T:::::T TTTTTTTTTTTT T:::::T TTTTTT C:::::C T:::::T T:::::T C:::::C T:::::T T:::::T C:::::C T:::::T T:::::T C:::::C T:::::T T:::::T C:::::C T:::::T T:::::T C:::::C T:::::T T:::::T C:::::C CCCCCC T:::::T T:::::T C:::::CCCCCCCC::::C TT:::::::TT TT:::::::TT CC:::::::::::::::C T:::::::::T T:::::::::T CCC::::::::::::C T:::::::::T T:::::::::T CCCCCCCCCCCCC TTTTTTTTTTT TTTTTTTTTTT ====Chris Titus Tech===== =====Windows Toolbox===== "@ # Load the configuration files $sync.configs.applicationsHashtable = @{} $sync.configs.applications.PSObject.Properties | ForEach-Object { $sync.configs.applicationsHashtable[$_.Name] = $_.Value } $sync.configs.appxHashtable = @{} $sync.configs.appx.PSObject.Properties | ForEach-Object { $sync.configs.appxHashtable[$_.Name] = $_.Value } $sync.preferences.theme = "Auto" $sync.preferences.packagemanager = "Winget" if ($Preset) { Initialize-WinUtilRunspacePool | Out-Null # Selects the tweaks from $Preset varible Update-WinUtilSelections -flatJson $sync.configs.preset.$Preset # Run tweaks that were selected by Update-WinUtilSelections Invoke-WinUtilAutoRun # Cleanup and exit Close-WinUtilRunspacePool [System.GC]::Collect() Stop-Transcript return } if ($Config) { Initialize-WinUtilRunspacePool | Out-Null Invoke-WPFImpex -type "import" -Config $Config Invoke-WinUtilAutoRun # Cleanup and exit Close-WinUtilRunspacePool [System.GC]::Collect() Stop-Transcript return } [void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework') [xml]$XAML = $inputXML # Read the XAML file $readerOperationSuccessful = $false # There's more cases of failure then success. $reader = (New-Object System.Xml.XmlNodeReader $xaml) try { $sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader ) $readerOperationSuccessful = $true } catch [System.Management.Automation.MethodInvocationException] { Write-Host "We ran into a problem with the XAML code. Check the syntax for this control..." -ForegroundColor Red Write-Host $error[0].Exception.Message -ForegroundColor Red If ($error[0].Exception.Message -like "*button*") { write-Host "Ensure your <button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n" -ForegroundColor Red } } catch { Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed." -ForegroundColor Red } if (-NOT ($readerOperationSuccessful)) { Write-Host "Failed to parse xaml content using Windows.Markup.XamlReader's Load Method." -ForegroundColor Red Write-Host "Quitting WinUtil..." -ForegroundColor Red Close-WinUtilRunspacePool [System.GC]::Collect() exit 1 } # Setup the Window to follow listen for windows Theme Change events and update the winutil theme # throttle logic needed, because windows seems to send more than one theme change event per change $lastThemeChangeTime = [datetime]::MinValue $debounceInterval = [timespan]::FromSeconds(2) $sync.Form.Add_Loaded({ $interopHelper = New-Object System.Windows.Interop.WindowInteropHelper $sync.Form $hwndSource = [System.Windows.Interop.HwndSource]::FromHwnd($interopHelper.Handle) $hwndSource.AddHook({ param ( [System.IntPtr]$hwnd, [int]$msg, [System.IntPtr]$wParam, [System.IntPtr]$lParam, [ref]$handled ) $null = $hwnd, $wParam, $lParam # Check for the Event WM_SETTINGCHANGE (0x1001A) and validate that Button shows the icon for "Auto" => [char]0xF08C if (($msg -eq 0x001A) -and $sync.ThemeButton.Content -eq [char]0xF08C) { $currentTime = [datetime]::Now if ($currentTime - $lastThemeChangeTime -gt $debounceInterval) { Invoke-WinutilThemeChange -theme "Auto" $script:lastThemeChangeTime = $currentTime $handled = $true } } return 0 }) }) Invoke-WinutilThemeChange -theme $sync.preferences.theme # Build only the default tab before first paint; other tabs initialize on first activation. $sync.InitializedTabs = @{} Initialize-WinUtilTabContent -TabName "Install" # Future implementation: Add Windows Version to updates panel #Invoke-WPFUIElements -configVariable $sync.configs.updates -targetGridName "updatespanel" -columncount 1 #=========================================================================== # Store Form Objects In PowerShell #=========================================================================== $xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)} $sync.ChocoRadioButton.Add_Checked({ $sync.preferences.packagemanager = "Choco" }) $sync.WingetRadioButton.Add_Checked({ $sync.preferences.packagemanager = "Winget" }) switch ($sync.preferences.packagemanager) { "Choco" {$sync.ChocoRadioButton.IsChecked = $true; break} "Winget" {$sync.WingetRadioButton.IsChecked = $true; break} } $sync.keys | ForEach-Object { if($sync.$psitem) { if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") { if ($sync.Buttons -notcontains $psitem) { $sync["$psitem"].Add_Click({ [System.Object]$Sender = $args[0] Invoke-WPFButton $Sender.name }) $sync.Buttons.Add($psitem) | Out-Null } } if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "Button") { if ($sync.Buttons -notcontains $psitem) { $sync["$psitem"].Add_Click({ [System.Object]$Sender = $args[0] Invoke-WPFButton $Sender.name }) $sync.Buttons.Add($psitem) | Out-Null } } if ($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "TextBlock") { if ($sync["$psitem"].Name.EndsWith("Link")) { $sync["$psitem"].Add_MouseUp({ [System.Object]$Sender = $args[0] Start-Process $Sender.ToolTip -ErrorAction Stop }) } } } } #=========================================================================== # Setup and Show the Form #=========================================================================== # 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 $sync["Form"].Add_Closing({ Close-WinUtilRunspacePool [System.GC]::Collect() }) # Attach the event handler to the Click event $sync.SearchBarClearButton.Add_Click({ $sync.SearchBar.Text = "" $sync.SearchBarClearButton.Visibility = "Collapsed" # Focus the search bar after clearing the text $sync.SearchBar.Focus() $sync.SearchBar.SelectAll() }) # add some shortcuts for people that don't like clicking function Invoke-WinUtilFontScaleStep([double]$Step) { $sync.FontScalingSlider.Value = [math]::Max(0.75, [math]::Min(2.0, $sync.FontScalingSlider.Value + $Step)); Invoke-WinUtilFontScaling -ScaleFactor $sync.FontScalingSlider.Value } $commonKeyEvents = { # Prevent shortcuts from executing if a process is already running if ($sync.ProcessRunning -eq $true) { return } # Handle key presses of single keys switch ($_.Key) { "Escape" { $sync.SearchBar.Text = "" } } # Handle Alt key combinations for navigation if ($_.KeyboardDevice.Modifiers -eq "Alt") { $keyEventArgs = $_ switch ($_.SystemKey) { "I" { Invoke-WPFButton "WPFTab1BT"; $keyEventArgs.Handled = $true } # Navigate to Install tab and suppress Windows Warning Sound "T" { Invoke-WPFButton "WPFTab2BT"; $keyEventArgs.Handled = $true } # Navigate to Tweaks tab "C" { Invoke-WPFButton "WPFTab3BT"; $keyEventArgs.Handled = $true } # Navigate to Config tab "U" { Invoke-WPFButton "WPFTab4BT"; $keyEventArgs.Handled = $true } # Navigate to Updates tab "W" { Invoke-WPFButton "WPFTab5BT"; $keyEventArgs.Handled = $true } # Navigate to Win11ISO tab } } # Handle Ctrl key combinations for specific actions if ($_.KeyboardDevice.Modifiers -eq "Ctrl") { $keyEventArgs = $_ switch ($_.Key) { "F" { $sync.SearchBar.Focus() } # Focus on the search bar "Q" { $this.Close() } # Close the application } } $ctrlShiftModifiers = [Windows.Input.ModifierKeys]::Control -bor [Windows.Input.ModifierKeys]::Shift if ($_.KeyboardDevice.Modifiers -eq "Ctrl" -or $_.KeyboardDevice.Modifiers -eq $ctrlShiftModifiers) { $keyEventArgs = $_ switch ($_.Key) { { $_ -in "OemPlus", "Add" } { Invoke-WinUtilFontScaleStep 0.05; $keyEventArgs.Handled = $true } { $_ -in "OemMinus", "Subtract" } { Invoke-WinUtilFontScaleStep -0.05; $keyEventArgs.Handled = $true } } } } $sync["Form"].Add_PreViewKeyDown($commonKeyEvents) $sync["Form"].Add_PreviewMouseWheel({ if ([Windows.Input.Keyboard]::Modifiers -eq "Ctrl") { Invoke-WinUtilFontScaleStep $(if ($_.Delta -gt 0) { 0.05 } else { -0.05 }); $_.Handled = $true } }) $sync["Form"].Add_MouseLeftButtonDown({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings", "Theme", "FontScaling") $sync["Form"].DragMove() }) $sync["Form"].Add_MouseDoubleClick({ if ($_.OriginalSource.Name -eq "NavDockPanel" -or $_.OriginalSource.Name -eq "GridBesideNavDockPanel") { if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) { $sync["Form"].WindowState = [Windows.WindowState]::Maximized } else{ $sync["Form"].WindowState = [Windows.WindowState]::Normal } } }) $sync["Form"].Add_Deactivated({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings", "Theme", "FontScaling") }) $sync["Form"].Add_ContentRendered({ # Load the Windows Forms assembly Add-Type -AssemblyName System.Windows.Forms $primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen # Check if the primary screen is found if ($primaryScreen) { # Extract screen width and height for the primary monitor $screenWidth = $primaryScreen.Bounds.Width $screenHeight = $primaryScreen.Bounds.Height # Compare with the primary monitor size if ($sync.Form.ActualWidth -gt $screenWidth -or $sync.Form.ActualHeight -gt $screenHeight) { $sync.Form.Left = 0 $sync.Form.Top = 0 $sync.Form.Width = $screenWidth $sync.Form.Height = $screenHeight } } if ($PARAM_OFFLINE) { # Show offline banner $sync.WPFOfflineBanner.Visibility = [System.Windows.Visibility]::Visible # Disable the install tab $sync.WPFTab1BT.IsEnabled = $false $sync.WPFTab1BT.Opacity = 0.5 $sync.WPFTab1BT.ToolTip = "Internet connection required for installing applications." # Disable install-related buttons $sync.WPFInstall.IsEnabled = $false $sync.WPFUninstall.IsEnabled = $false $sync.WPFInstallUpgrade.IsEnabled = $false $sync.WPFGetInstalled.IsEnabled = $false # Show offline indicator Write-Host "Offline mode detected - Install tab disabled." -ForegroundColor Yellow # Optionally switch to a different tab if install tab was going to be default Invoke-WPFTab "WPFTab2BT" # Switch to Tweaks tab instead } else { # Online - ensure install tab is enabled $sync.WPFTab1BT.IsEnabled = $true $sync.WPFTab1BT.Opacity = 1.0 $sync.WPFTab1BT.ToolTip = $null Invoke-WPFTab "WPFTab1BT" # Default to install tab } $sync["Form"].Focus() $sync["Form"].Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Initialize-WinUtilRunspacePool | Out-Null }) | Out-Null $sync["Form"].Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $false -IncludeStatusAssets $true }) | Out-Null }) # The SearchBarTimer is used to delay the search operation until the user has stopped typing for a short period # This prevents the ui from stuttering when the user types quickly as it dosnt need to update the ui for every keystroke $searchBarTimer = New-Object System.Windows.Threading.DispatcherTimer $searchBarTimer.Interval = [TimeSpan]::FromMilliseconds(300) $searchBarTimer.IsEnabled = $false $searchBarTimer.add_Tick({ $searchBarTimer.Stop() switch ($sync.currentTab) { "Install" { Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text } "Tweaks" { Find-TweaksByNameOrDescription -SearchString $sync.SearchBar.Text } "AppX" { Find-TweaksByNameOrDescription -SearchString $sync.SearchBar.Text } } }) $sync["SearchBar"].Add_TextChanged({ if ($sync.SearchBar.Text -ne "") { $sync.SearchBarClearButton.Visibility = "Visible" } else { $sync.SearchBarClearButton.Visibility = "Collapsed" } if ($searchBarTimer.IsEnabled) { $searchBarTimer.Stop() } $searchBarTimer.Start() }) $sync["Form"].Add_Loaded({ param($e) $null = $e $sync.Form.MinWidth = "1000" $sync["Form"].MaxWidth = [Double]::PositiveInfinity $sync["Form"].MaxHeight = [Double]::PositiveInfinity }) $NavLogoPanel = $sync["Form"].FindName("NavLogoPanel") $NavLogoPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) | Out-Null Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $true -IncludeStatusAssets $false Set-WinUtilTaskbaritem -overlay "logo" $sync["Form"].Add_Activated({ Set-WinUtilTaskbaritem -overlay "logo" }) $sync["ThemeButton"].Add_Click({ Invoke-WPFPopup -PopupActionTable @{ "Settings" = "Hide"; "Theme" = "Toggle"; "FontScaling" = "Hide" } }) $sync["AutoThemeMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Theme") Invoke-WinutilThemeChange -theme "Auto" }) $sync["DarkThemeMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Theme") Invoke-WinutilThemeChange -theme "Dark" }) $sync["LightThemeMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Theme") Invoke-WinutilThemeChange -theme "Light" }) $sync["SettingsButton"].Add_Click({ Invoke-WPFPopup -PopupActionTable @{ "Settings" = "Toggle"; "Theme" = "Hide"; "FontScaling" = "Hide" } }) $sync["ImportMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings") Invoke-WPFImpex -type "import" }) $sync["ExportMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings") Invoke-WPFImpex -type "export" }) $sync["AboutMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings") $authorInfo = @" Author : @ChrisTitusTech UI : @MyDrift-user, @Marterich Runspace : @DeveloperDurp, @Marterich GitHub : ChrisTitusTech/winutil Version : $($sync.version) "@ Show-CustomDialog -Title "About" -Message $authorInfo }) $sync["DocumentationMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings") Start-Process "https://winutil.christitus.com/" }) $sync["SponsorMenuItem"].Add_Click({ Invoke-WPFPopup -Action "Hide" -Popups @("Settings") $authorInfo = @" Current sponsors for ChrisTitusTech: "@ $authorInfo += "`n" try { $sponsors = Invoke-WinUtilSponsors foreach ($sponsor in $sponsors) { $authorInfo += "$sponsor`n" } } catch { $authorInfo += "An error occurred while fetching or processing the sponsors: $_`n" } Show-CustomDialog -Title "Sponsors" -Message $authorInfo -EnableScroll $true }) # Font Scaling Event Handlers $sync["FontScalingButton"].Add_Click({ Invoke-WPFPopup -PopupActionTable @{ "Settings" = "Hide"; "Theme" = "Hide"; "FontScaling" = "Toggle" } }) $sync["FontScalingSlider"].Add_ValueChanged({ param($slider) $percentage = [math]::Round($slider.Value * 100) $sync.FontScalingValue.Text = "$percentage%" }) $sync["FontScalingResetButton"].Add_Click({ $sync.FontScalingSlider.Value = 1.0 $sync.FontScalingValue.Text = "100%" }) $sync["FontScalingApplyButton"].Add_Click({ $scaleFactor = $sync.FontScalingSlider.Value Invoke-WinUtilFontScaling -ScaleFactor $scaleFactor Invoke-WPFPopup -Action "Hide" -Popups @("FontScaling") }) # ── Win11ISO Tab button handlers ────────────────────────────────────────────── $sync["WPFWin11ISOBrowseButton"].Add_Click({ Invoke-WinUtilISOBrowse }) $sync["WPFWin11ISODownloadLink"].Add_Click({ Start-Process "https://www.microsoft.com/software-download/windows11" }) $sync["WPFWin11ISOMountButton"].Add_Click({ Invoke-WinUtilISOMountAndVerify }) $sync["WPFWin11ISOModifyButton"].Add_Click({ Invoke-WinUtilISOModify }) $sync["WPFWin11ISOChooseISOButton"].Add_Click({ $sync["WPFWin11ISOOptionUSB"].Visibility = "Collapsed" Invoke-WinUtilISOExport }) $sync["WPFWin11ISOChooseUSBButton"].Add_Click({ $sync["WPFWin11ISOOptionUSB"].Visibility = "Visible" Invoke-WinUtilISORefreshUSBDrives }) $sync["WPFWin11ISORefreshUSBButton"].Add_Click({ Invoke-WinUtilISORefreshUSBDrives }) $sync["WPFWin11ISOWriteUSBButton"].Add_Click({ Invoke-WinUtilISOWriteUSB }) $sync["WPFWin11ISOCleanResetButton"].Add_Click({ Invoke-WinUtilISOCleanAndReset }) # ────────────────────────────────────────────────────────────────────────────── $sync["Form"].ShowDialog() | out-null Stop-Transcript