Merge branch 'main' into simplify02

This commit is contained in:
Chris Titus 2025-04-16 09:01:46 -05:00 committed by GitHub
commit aae5bbb752
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 369 additions and 234 deletions

View File

@ -527,14 +527,6 @@
"link": "https://espanso.org/",
"winget": "Espanso.Espanso"
},
"etcher": {
"category": "Utilities",
"choco": "etcher",
"content": "Etcher USB Creator",
"description": "Etcher is a powerful tool for creating bootable USB drives with ease.",
"link": "https://www.balena.io/etcher/",
"winget": "Balena.Etcher"
},
"falkon": {
"category": "Browsers",
"choco": "falkon",

View File

@ -2,6 +2,7 @@
"Standard": [
"WPFTweaksAH",
"WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksDVR",
"WPFTweaksHiber",
"WPFTweaksHome",
@ -18,6 +19,7 @@
],
"Minimal": [
"WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksHome",
"WPFTweaksServices",
"WPFTweaksTele"

View File

@ -35,7 +35,8 @@
"CheckboxMouseOverColor": "#999999",
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2"
"ButtonCornerRadius": "2",
"AppTileImageSize": "40"
},
"Light": {
"AppInstallUnselectedColor": "#F0F0F0",

View File

@ -3758,5 +3758,60 @@
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/RemoveUltPerf"
}
},
"WPFTweaksDisableExplorerAutoDiscovery": {
"Content": "Disable Explorer Automatic Folder Discovery",
"Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience.",
"category": "Essential Tweaks",
"panel": "1",
"Order": "a005_",
"InvokeScript": [
"
# Previously detected folders
$bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"
# Folder types lookup table
$bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"
# Flush explorer view database
Remove-Item -Path $bags -Recurse -Force
Write-Host \"Removed $bags\"
Remove-Item -Path $bagMRU -Recurse -Force
Write-Host \"Removed $bagMRU\"
# Every folder
$allFolders = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\\AllFolders\\Shell\"
if (!(Test-Path $allFolders)) {
New-Item -Path $allFolders -Force
Write-Host \"Created $allFolders\"
}
# Generic view
New-ItemProperty -Path $allFolders -Name \"FolderType\" -Value \"NotSpecified\" -PropertyType String -Force
Write-Host \"Set FolderType to NotSpecified\"
Write-Host Please sign out and back in, or restart your computer to apply the changes!
"
],
"UndoScript": [
"
# Previously detected folders
$bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"
# Folder types lookup table
$bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"
# Flush explorer view database
Remove-Item -Path $bags -Recurse -Force
Write-Host \"Removed $bags\"
Remove-Item -Path $bagMRU -Recurse -Force
Write-Host \"Removed $bagMRU\"
Write-Host Please sign out and back in, or restart your computer to apply the changes!
"
],
},
}

View File

@ -0,0 +1,59 @@
function Get-WinUtilSelectedPackages
{
<#
.SYNOPSIS
Sorts given packages based on installer preference and availability.
.OUTPUTS
Hashtable. Key = Package Manager, Value = ArrayList of packages to install
#>
param (
[Parameter(Mandatory=$true)]
$PackageList,
[Parameter(Mandatory=$true)]
[PackageManagers]$Preference
)
if ($PackageList.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" })
}
$packages = [System.Collections.Hashtable]::new()
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
$packages[[PackageManagers]::Winget] = $packagesWinget
$packages[[PackageManagers]::Choco] = $packagesChoco
Write-Debug "Checking packages using Preference '$($Preference)'"
foreach ($package in $PackageList) {
switch ($Preference) {
"Choco" {
if ($package.choco -eq "na") {
Write-Debug "$($package.content) has no Choco value."
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey"
}
break
}
"Winget" {
if ($package.winget -eq "na") {
Write-Debug "$($package.content) has no Winget value."
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget"
}
break
}
}
}
return $packages
}

View File

@ -5,28 +5,23 @@ function Initialize-InstallAppEntry {
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The Element into which the Apps should be placed
.PARAMETER AppKey
.PARAMETER appKey
The Key of the app inside the $sync.configs.applicationsHashtable
#>
param(
[Windows.Controls.WrapPanel]$TargetElement,
$AppKey
$appKey
)
$App = $sync.configs.applicationsHashtable.$AppKey
# Create the outer Border for the application type
$border = New-Object Windows.Controls.Border
$border.BorderBrush = [Windows.Media.Brushes]::Gray
$border.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "AppTileBorderThickness")
$border.CornerRadius = 5
$border.SetResourceReference([Windows.Controls.Control]::PaddingProperty, "AppTileMargins")
$border.SetResourceReference([Windows.Controls.Control]::WidthProperty, "AppTileWidth")
$border.VerticalAlignment = "Top"
$border.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
$border.Cursor = [System.Windows.Input.Cursors]::Hand
$border.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
$border.Tag = $Appkey
$border.ToolTip = $App.description
$border.Style = $sync.Form.Resources.AppTileBorderStyle
$border.Tag = $appKey
$border.ToolTip = $Apps.$appKey.description
$border.Add_MouseUp({
if ($_.ChangedButton -eq [System.Windows.Input.MouseButton]::Right) {
Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*";
}
$childCheckbox = ($this.Child.Children | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0]
$childCheckBox.isChecked = -not $childCheckbox.IsChecked
})
@ -47,12 +42,8 @@ function Initialize-InstallAppEntry {
# Create the CheckBox, vertically centered
$checkBox = New-Object Windows.Controls.CheckBox
$checkBox.Name = $AppKey
$checkBox.Background = "Transparent"
$checkBox.HorizontalAlignment = "Left"
$checkBox.VerticalAlignment = "Center"
$checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
$checkBox.SetResourceReference([Windows.Controls.Control]::StyleProperty, "CollapsedCheckBoxStyle")
$checkBox.Name = $appKey
$checkbox.Style = $sync.Form.Resources.AppTileCheckboxStyle
$checkbox.Add_Checked({
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $this
$borderElement = $this.Parent.Parent
@ -64,7 +55,7 @@ function Initialize-InstallAppEntry {
$borderElement = $this.Parent.Parent
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
})
$sync.$($checkBox.Name) = $checkBox
# Create a StackPanel for the image and name
$imageAndNamePanel = New-Object Windows.Controls.StackPanel
$imageAndNamePanel.Orientation = "Horizontal"
@ -73,29 +64,15 @@ function Initialize-InstallAppEntry {
# Create the Image and set a placeholder
$image = New-Object Windows.Controls.Image
# $image.Name = "wpfapplogo" + $App.Name
$image.Width = 40
$image.Height = 40
$image.Margin = New-Object Windows.Thickness(0, 0, 10, 0)
$image.Style = $sync.Form.Resources.AppTileImageStyle
$image.Source = $noimage # Ensure $noimage is defined in your script
# Clip the image corners
$image.Clip = New-Object Windows.Media.RectangleGeometry
$image.Clip.Rect = New-Object Windows.Rect(0, 0, $image.Width, $image.Height)
$image.Clip.RadiusX = 5
$image.Clip.RadiusY = 5
$image.SetResourceReference([Windows.Controls.Control]::VisibilityProperty, "AppTileCompactVisibility")
$imageAndNamePanel.Children.Add($image) | Out-Null
# Create the TextBlock for the application name
$appName = New-Object Windows.Controls.TextBlock
$appName.Text = $App.Content
$appName.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "AppTileFontSize")
$appName.FontWeight = [Windows.FontWeights]::Bold
$appName.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$appName.VerticalAlignment = "Center"
$appName.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
$appName.Background = "Transparent"
$appName.Style = $sync.Form.Resources.AppTileNameStyle
$appName.Text = $Apps.$appKey.content
$imageAndNamePanel.Children.Add($appName) | Out-Null
# Add the image and name panel to the Checkbox
@ -107,91 +84,53 @@ function Initialize-InstallAppEntry {
# Create the StackPanel for the buttons and dock it to the right
$buttonPanel = New-Object Windows.Controls.StackPanel
$buttonPanel.Orientation = "Horizontal"
$buttonPanel.HorizontalAlignment = "Right"
$buttonPanel.VerticalAlignment = "Center"
$buttonPanel.SetResourceReference([Windows.Controls.Control]::MarginProperty, "AppTileMargins")
$buttonPanel.SetResourceReference([Windows.Controls.Control]::VisibilityProperty, "AppTileCompactVisibility")
$buttonPanel.Style = $sync.Form.Resources.AppTileButtonPanelStyle
[Windows.Controls.DockPanel]::SetDock($buttonPanel, [Windows.Controls.Dock]::Right)
# Create the "Install" button
$installButton = New-Object Windows.Controls.Button
$installButton.Width = 45
$installButton.Height = 35
$installButton.Margin = New-Object Windows.Thickness(0, 0, 10, 0)
# Define the button properties
$buttons = @(
[PSCustomObject]@{ Name = "Install"; Description = "Install or Upgrade the application"; Tooltip = "Install or Upgrade the application"; Icon = [char]0xE118 },
[PSCustomObject]@{ Name = "Uninstall"; Description = "Uninstall the application"; Tooltip = "Uninstall the application"; Icon = [char]0xE74D },
[PSCustomObject]@{ Name = "Info"; Description = "Open the application's website in your default browser"; Tooltip = "Open the application's website in your default browser"; Icon = [char]0xE946 }
)
$installIcon = New-Object Windows.Controls.TextBlock
$installIcon.Text = [char]0xE118 # Install Icon
$installIcon.FontFamily = "Segoe MDL2 Assets"
$installIcon.FontSize = 20
$installIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$installIcon.Background = "Transparent"
$installIcon.HorizontalAlignment = "Center"
$installIcon.VerticalAlignment = "Center"
# Iterate over each button and create it
foreach ($button in $buttons) {
$newButton = New-Object Windows.Controls.Button
$newButton.Style = $sync.Form.Resources.AppTileButtonStyle
$newButton.Content = $button.Icon
$newButton.ToolTip = $button.Tooltip
$buttonPanel.Children.Add($newButton) | Out-Null
$installButton.Content = $installIcon
$installButton.ToolTip = "Install or Upgrade the application"
$buttonPanel.Children.Add($installButton) | Out-Null
# Add Click event for the "Install" button
$installButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFInstall -PackagesToInstall $appObject
})
# Create the "Uninstall" button
$uninstallButton = New-Object Windows.Controls.Button
$uninstallButton.Width = 45
$uninstallButton.Height = 35
$uninstallIcon = New-Object Windows.Controls.TextBlock
$uninstallIcon.Text = [char]0xE74D # Uninstall Icon
$uninstallIcon.FontFamily = "Segoe MDL2 Assets"
$uninstallIcon.FontSize = 20
$uninstallIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$uninstallIcon.Background = "Transparent"
$uninstallIcon.HorizontalAlignment = "Center"
$uninstallIcon.VerticalAlignment = "Center"
$uninstallButton.Content = $uninstallIcon
$buttonPanel.Children.Add($uninstallButton) | Out-Null
$uninstallButton.ToolTip = "Uninstall the application"
$uninstallButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFUnInstall -PackagesToUninstall $appObject
})
# Create the "Info" button
$infoButton = New-Object Windows.Controls.Button
$infoButton.Width = 45
$infoButton.Height = 35
$infoButton.Margin = New-Object Windows.Thickness(10, 0, 0, 0)
$infoIcon = New-Object Windows.Controls.TextBlock
$infoIcon.Text = [char]0xE946 # Info Icon
$infoIcon.FontFamily = "Segoe MDL2 Assets"
$infoIcon.FontSize = 20
$infoIcon.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$infoIcon.Background = "Transparent"
$infoIcon.HorizontalAlignment = "Center"
$infoIcon.VerticalAlignment = "Center"
$infoButton.Content = $infoIcon
$infoButton.ToolTip = "Open the application's website in your default browser"
$buttonPanel.Children.Add($infoButton) | Out-Null
$infoButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Start-Process $appObject.link
})
switch ($button.Name) {
"Install" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFInstall -PackagesToInstall $appObject
})
}
"Uninstall" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFUnInstall -PackagesToUninstall $appObject
})
}
"Info" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Start-Process $appObject.link
})
}
}
}
# Add the button panel to the DockPanel
$dockPanel.Children.Add($buttonPanel) | Out-Null
# Add the border to the corresponding Category
$TargetElement.Children.Add($border) | Out-Null
return $checkbox
}

View File

@ -53,8 +53,17 @@ function Initialize-InstallCategoryAppList {
$TargetElement.Dispatcher.Invoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{
$TargetElement.Items.Clear() # Remove the loading message
$categories = $Apps.Values | Select-Object -ExpandProperty category -Unique | Sort-Object
foreach ($category in $categories) {
# Pre-group apps by category
$appsByCategory = @{}
foreach ($appKey in $Apps.Keys) {
$category = $Apps.$appKey.Category
if (-not $appsByCategory.ContainsKey($category)) {
$appsByCategory[$category] = @()
}
$appsByCategory[$category] += $appKey
}
foreach ($category in $($appsByCategory.Keys | Sort-Object)) {
Add-Category -Category $category -TargetElement $TargetElement
$wrapPanel = New-Object Windows.Controls.WrapPanel
$wrapPanel.Orientation = "Horizontal"
@ -64,9 +73,9 @@ function Initialize-InstallCategoryAppList {
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
$wrapPanel.Tag = "CategoryWrapPanel_$category"
$null = $TargetElement.Items.Add($wrapPanel)
$Apps.Keys | Where-Object { $Apps.$_.Category -eq $category } | Sort-Object | ForEach-Object {
Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_
}
$appsByCategory[$category] |Sort-Object | ForEach-Object {
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)
}
})
}
})
}

View File

@ -0,0 +1,43 @@
function Set-PackageManagerPreference {
<#
.SYNOPSIS
Sets the currently selected package manager to global "ManagerPreference" in sync.
Also persists preference across Winutil restarts via preference.ini.
Reads from preference.ini if no argument sent.
.PARAMETER preferedPackageManager
The PackageManager that was selected.
#>
param(
[Parameter(Position=0, Mandatory=$false)]
[PackageManagers]$preferedPackageManager
)
$preferencePath = "$env:LOCALAPPDATA\winutil\preferences.ini"
$oldChocoPath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
#Try loading from file if no argument given.
if ($null -eq $preferedPackageManager) {
# Backwards compat for preferChocolatey.ini
if (Test-Path -Path $oldChocoPath) {
$preferedPackageManager = [PackageManagers]::Choco
Remove-Item -Path $oldChocoPath
}
elseif (Test-Path -Path $preferencePath) {
$potential = Get-Content -Path $preferencePath -TotalCount 1
$preferedPackageManager = [PackageManagers]$potential
}
else {
Write-Debug "Creating new preference file, defaulting to winget."
$preferedPackageManager = [PackageManagers]::Winget
}
}
$sync["ManagerPreference"] = [PackageManagers]::$preferedPackageManager
Write-Debug "Manager Preference changed to '$($sync["ManagerPreference"])'"
# Write preference to file to persist across restarts.
Out-File -FilePath $preferencePath -InputObject $sync["ManagerPreference"]
}

View File

@ -18,15 +18,15 @@ function Invoke-WPFGetInstalled {
if (($sync.ChocoRadioButton.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
return
}
$preferChoco = $sync.ChocoRadioButton.IsChecked
$managerPreference = $sync["ManagerPreference"]
$sync.ItemsControl.Dispatcher.Invoke([action] {
$sync.ItemsControl.Items | ForEach-Object { $_.Visibility = [Windows.Visibility]::Collapsed }
$null = $sync.itemsControl.Items.Add($sync.LoadingLabel)
})
Invoke-WPFRunspace -ParameterList @(("preferChoco", $preferChoco),("checkbox", $checkbox),("ShowOnlyCheckedApps", ${function:Show-OnlyCheckedApps})) -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox),("ShowOnlyCheckedApps", ${function:Show-OnlyCheckedApps})) -DebugPreference $DebugPreference -ScriptBlock {
param (
[string]$checkbox,
[boolean]$preferChoco,
[PackageManagers]$managerPreference,
[scriptblock]$ShowOnlyCheckedApps
)
$sync.ProcessRunning = $true
@ -34,8 +34,10 @@ function Invoke-WPFGetInstalled {
if ($checkbox -eq "winget") {
Write-Host "Getting Installed Programs..."
if ($preferChoco) { $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco" }
else { $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox }
switch ($managerPreference) {
"Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break}
"Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break}
}
}
elseif ($checkbox -eq "tweaks") {
Write-Host "Getting Installed Tweaks..."

View File

@ -21,40 +21,16 @@ function Invoke-WPFInstall {
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
$ChocoPreference = $($sync.ChocoRadioButton.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $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.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
foreach ($package in $PackagesToInstall) {
if ($ChocoPreference) {
if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget install"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
}
}
else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget install"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall)
$ManagerPreference = $sync["ManagerPreference"]
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ManagerPreference, $DebugPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
try {
$sync.ProcessRunning = $true

View File

@ -29,46 +29,20 @@ function Invoke-WPFUnInstall {
$confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
if($confirm -eq "No") {return}
$ChocoPreference = $($sync.ChocoRadioButton.IsChecked)
Invoke-WPFRunspace -ArgumentList @(("PackagesToUninstall", $PackagesToUninstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToUninstall, $ChocoPreference, $DebugPreference)
if ($PackagesToUninstall.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.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
$ManagerPreference = $sync["ManagerPreference"]
foreach ($package in $PackagesToUninstall) {
if ($ChocoPreference) {
if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget uninstall"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
}
}
else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget uninstall"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToUninstall)
Invoke-WPFRunspace -ArgumentList @(("PackagesToUninstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToUninstall, $ManagerPreference, $DebugPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
try {
$sync.ProcessRunning = $true
# Install all selected programs in new window
# Uninstall all selected programs in new window
if($packagesWinget.Count -gt 0) {
Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget
}

View File

@ -1,3 +1,12 @@
# Create enums
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
# SPDX-License-Identifier: MIT
# Set the maximum number of threads for the RunspacePool to the number of threads on the machine
$maxthreads = [int]$env:NUMBER_OF_PROCESSORS
@ -46,7 +55,6 @@ class GenericException : Exception {
GenericException($Message) : base($Message) {}
}
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
@ -119,18 +127,18 @@ $sync.configs.applications.PSObject.Properties | ForEach-Object {
# Now call the function with the final merged config
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
# Add logic to handle click to the ToggleView Button on the Install Tab
$sync.WPFToggleView.Add_Click({
$sync.CompactView = -not $sync.CompactView
Update-AppTileProperties
if ($sync.SearchBar.Text -eq "") {
Set-CategoryVisibility -Category "*"
}
})
Invoke-WPFUIApps -Apps $sync.configs.applicationsHashtable -targetGridName "appspanel"
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
# Future implementation: Add Windows Version to updates panel
#Invoke-WPFUIElements -configVariable $sync.configs.updates -targetGridName "updatespanel" -columncount 1
@ -140,12 +148,14 @@ Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "feat
$xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)}
#Persist the Chocolatey preference across winutil restarts
$ChocoPreferencePath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
$sync.ChocoRadioButton.Add_Checked({New-Item -Path $ChocoPreferencePath -Force })
$sync.ChocoRadioButton.Add_Unchecked({Remove-Item $ChocoPreferencePath -Force})
if (Test-Path $ChocoPreferencePath) {
$sync.ChocoRadioButton.IsChecked = $true
#Persist Package Manager preference across winutil restarts
$sync.ChocoRadioButton.Add_Checked({Set-PackageManagerPreference Choco})
$sync.WingetRadioButton.Add_Checked({Set-PackageManagerPreference Winget})
Set-PackageManagerPreference
switch ($sync["ManagerPreference"]) {
"Choco" {$sync.ChocoRadioButton.IsChecked = $true; break}
"Winget" {$sync.WingetRadioButton.IsChecked = $true; break}
}
$sync.keys | ForEach-Object {
@ -184,7 +194,6 @@ $sync.keys | ForEach-Object {
# Load computer information in the background
Invoke-WPFRunspace -ScriptBlock {
try {
$oldProgressPreference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
$sync.ConfigLoaded = $False
$sync.ComputerInfo = Get-ComputerInfo
@ -208,6 +217,7 @@ $sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
$sync.Form.Resources.AppTileFontSize = [double]16
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
function Update-AppTileProperties {
if ($sync.CompactView -eq $true) {
$sync.Form.Resources.AppTileWidth = [double]::NaN
@ -217,13 +227,24 @@ function Update-AppTileProperties {
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
}
else {
$sync.Form.Resources.AppTileWidth = $sync.ItemsControl.ActualWidth -20
# On first load, set the AppTileWidth to NaN because the Window dosnt exist yet and there is no ActuaWidth
if ($sync.ItemsControl.ActualWidth -gt 0) {
$sync.Form.Resources.AppTileWidth = $sync.ItemsControl.ActualWidth -20}
else {
$sync.Form.Resources.AppTileWidth = [double]::NaN
}
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
$sync.Form.Resources.AppTileFontSize = [double]16
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]1
}
if ($sync.SearchBar.Text -eq "") {
Set-CategoryVisibility -Category "*"
}
}
# initialize AppTile properties
Update-AppTileProperties
# We need to update the app tile properties when the form is resized because to fill a WrapPanel update the width of the elemenmt manually (afaik)
$sync.Form.Add_SizeChanged({
Update-AppTileProperties
@ -303,8 +324,8 @@ $sync["Form"].Add_MouseLeftButtonDown({
})
$sync["Form"].Add_MouseDoubleClick({
if ($_.OriginalSource -is [System.Windows.Controls.Grid] -or
$_.OriginalSource -is [System.Windows.Controls.StackPanel]) {
if ($_.OriginalSource.Name -eq "NavDockPanel" -or
$_.OriginalSource.Name -eq "GridBesideNavDockPanel") {
if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) {
$sync["Form"].WindowState = [Windows.WindowState]::Maximized
}
@ -579,7 +600,5 @@ $sync["SponsorMenuItem"].Add_Click({
Show-CustomDialog -Title "Sponsors" -Message $authorInfo -EnableScroll $true
})
$sync["Form"].ShowDialog() | out-null
Stop-Transcript

View File

@ -42,6 +42,7 @@ $sync.ProcessRunning = $false
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
$sync.ShowOnlySeleced = $false
$sync.currentTab = "Install"
$sync.CompactView = $true
$sync.ShowOnlySelected = $false
$sync.selectedAppsStackPanel
$sync.selectedAppsPopup

View File

@ -67,6 +67,82 @@
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="AppTileBorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="{DynamicResource AppTileBorderThickness}"/>
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="Padding" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Width" Value="{DynamicResource AppTileWidth}"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="{DynamicResource AppInstallUnselectedColor}"/>
</Style>
<Style x:Key="AppTileCheckboxStyle" TargetType="CheckBox">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<ContentPresenter Content="{TemplateBinding Content}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AppTileImageStyle" TargetType="Image">
<Setter Property="Width" Value="{DynamicResource AppTileImageSize}"/>
<Setter Property="Height" Value="{DynamicResource AppTileImageSize}"/>
<Setter Property="Margin">
<Setter.Value>
<Thickness Left="0" Top="0" Right="10" Bottom="0"/>
</Setter.Value>
</Setter>
<Setter Property="Clip">
<Setter.Value>
<RectangleGeometry Rect="0,0,40,40" RadiusX="5" RadiusY="5"/>
</Setter.Value>
</Setter>
<Setter Property="Visibility" Value="{DynamicResource AppTileCompactVisibility}"/>
</Style>
<Style x:Key="AppTileNameStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="{DynamicResource AppTileFontSize}"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style x:Key="AppTileButtonPanelStyle" TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Visibility" Value="{DynamicResource AppTileCompactVisibility}"/>
</Style>
<Style x:Key="AppTileButtonStyle" TargetType="Button">
<Setter Property="Width" Value="45"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Margin" Value="0,0,10,0"/>
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundColor}"/>
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundColor}"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="Segoe MDL2 Assets" FontSize="20"
Foreground="{DynamicResource MainForegroundColor}"
Background="Transparent" HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Button" x:Key="HoverButtonStyle">
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
@ -502,19 +578,6 @@
</Setter.Value>
</Setter>
</Style>
<!-- Collapsed Checkbox Style -->
<Style x:Key="CollapsedCheckBoxStyle" TargetType="CheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<ContentPresenter Content="{TemplateBinding Content}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="RadioButton">
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}"/>
<Setter Property="Background" Value="{DynamicResource MainBackgroundColor}"/>
@ -851,7 +914,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DockPanel HorizontalAlignment="Stretch" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto">
<DockPanel Name="NavDockPanel" HorizontalAlignment="Stretch" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto">
<StackPanel Name="NavLogoPanel" Orientation="Horizontal" HorizontalAlignment="Left" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Margin="10,0,20,0">
</StackPanel>
<ToggleButton Margin="0,0,5,0" HorizontalAlignment="Left" Height="{DynamicResource TabButtonHeight}" Width="{DynamicResource TabButtonWidth}"
@ -894,7 +957,7 @@
</TextBlock>
</ToggleButton.Content>
</ToggleButton>
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid Name="GridBesideNavDockPanel" Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <!-- Main content area -->
<ColumnDefinition Width="Auto"/><!-- Space for options button -->