mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 17:41:14 +10:00
* Add Quick Category Search Chips to Install tab Add category shortcut chips on the Install tab that insert the category name into the existing search box. Append each app's category as a description tag so the existing description search filters by category. Reuses the standard button style and existing search; no search, install, or preset logic is changed. * Fix install category chip filtering * Fix category filter refresh behavior --------- Co-authored-by: Chris Titus <contact@christitus.com>
535 lines
20 KiB
PowerShell
535 lines
20 KiB
PowerShell
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
|
|
$sync.Form.MinWidth = [Math]::Min([double]$sync.Form.MinWidth, [double]$screenWidth)
|
|
|
|
# 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 -Category $sync.SearchBar.Tag
|
|
}
|
|
"Tweaks" {
|
|
Find-TweaksByNameOrDescription -SearchString $sync.SearchBar.Text
|
|
}
|
|
"AppX" {
|
|
Find-TweaksByNameOrDescription -SearchString $sync.SearchBar.Text
|
|
}
|
|
}
|
|
})
|
|
$sync["SearchBar"].Add_TextChanged({
|
|
if ($sync.SearchBar.Tag -ne $sync.SearchBar.Text) {
|
|
$sync.SearchBar.Tag = $null
|
|
}
|
|
|
|
if ($sync.SearchBar.Text -ne "") {
|
|
$sync.SearchBarClearButton.Visibility = "Visible"
|
|
$sync.SearchBarIcon.Visibility = "Collapsed"
|
|
} else {
|
|
$sync.SearchBarClearButton.Visibility = "Collapsed"
|
|
$sync.SearchBarIcon.Visibility = "Visible"
|
|
}
|
|
|
|
# Category chip handlers apply their filter immediately.
|
|
if ($sync.SearchBar.Tag -eq $sync.SearchBar.Text) {
|
|
return
|
|
}
|
|
|
|
if ($searchBarTimer.IsEnabled) {
|
|
$searchBarTimer.Stop()
|
|
}
|
|
$searchBarTimer.Start()
|
|
})
|
|
|
|
# Quick Category Search Chips
|
|
$sync["WPFSearchChipAll"].Add_Click({ Set-WinUtilAppCategoryFilter })
|
|
$sync["WPFSearchChipBrowsers"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Browsers" })
|
|
$sync["WPFSearchChipCommunications"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Communications" })
|
|
$sync["WPFSearchChipDevelopment"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Development" })
|
|
$sync["WPFSearchChipGames"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Games" })
|
|
$sync["WPFSearchChipMicrosoftTools"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Microsoft Tools" })
|
|
$sync["WPFSearchChipMultimediaTools"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Multimedia Tools" })
|
|
$sync["WPFSearchChipProTools"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Pro Tools" })
|
|
$sync["WPFSearchChipSelfhostedTools"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Selfhosted Tools" })
|
|
$sync["WPFSearchChipUtilities"].Add_Click({ Set-WinUtilAppCategoryFilter -Category "Utilities" })
|
|
|
|
$sync["Form"].Add_Loaded({
|
|
param($e)
|
|
$null = $e
|
|
$sync.Form.MinWidth = "1150"
|
|
$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 : <a href="https://github.com/ChrisTitusTech">@ChrisTitusTech</a>
|
|
UI : <a href="https://github.com/MyDrift-user">@MyDrift-user</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
|
Runspace : <a href="https://github.com/DeveloperDurp">@DeveloperDurp</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
|
GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a>
|
|
Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sync.version)">$($sync.version)</a>
|
|
"@
|
|
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 = @"
|
|
<a href="https://github.com/sponsors/ChrisTitusTech">Current sponsors for ChrisTitusTech:</a>
|
|
"@
|
|
$authorInfo += "`n"
|
|
try {
|
|
$sponsors = Invoke-WinUtilSponsors
|
|
foreach ($sponsor in $sponsors) {
|
|
$authorInfo += "<a href=`"https://github.com/sponsors/ChrisTitusTech`">$sponsor</a>`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
|