From a296d0f43c8a2721f7a2b779520f64f351b90a58 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 10 Oct 2022 17:28:29 -0500 Subject: [PATCH 1/5] New Chocolatey Package Counter Gets the quantity of folders at `$env:ChocolateyInstall\lib`, which contains the programs Chocolatey has installed. --- winfetch.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winfetch.ps1 b/winfetch.ps1 index faf600d..57fb821 100644 --- a/winfetch.ps1 +++ b/winfetch.ps1 @@ -889,7 +889,7 @@ function info_pkgs { } if ("choco" -in $ShowPkgs -and (Get-Command -Name choco -ErrorAction Ignore)) { - $chocopkg = (& clist -l)[-1].Split(' ')[0] - 1 + $chocopkg = (Get-ChildItem -Path "$env:ChocolateyInstall\lib").count - 1 if ($chocopkg) { $pkgs += "$chocopkg (choco)" From 0678afb1b0449496ebe1f4231aeecb18076592ca Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Thu, 13 Oct 2022 10:25:39 -0500 Subject: [PATCH 2/5] Add "system" to ShowPkgs - Added "system" to info_pkgs as a faster alternative to "winget" - Returns the total quantity of 'uninstallable' programs - Quantity is different from what Winget returns due to the lack of its index, so this couldn't be used as a faster implementation of "winget" - Added "system" to default config file - Changed the returned string in "winget" to clarify that it is Winget and not the entire system --- winfetch.ps1 | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/winfetch.ps1 b/winfetch.ps1 index 57fb821..bb64e76 100644 --- a/winfetch.ps1 +++ b/winfetch.ps1 @@ -156,7 +156,7 @@ $defaultConfig = @' # Configure which package managers are shown # disabling unused ones will improve speed -# $ShowPkgs = @("winget", "scoop", "choco") +# $ShowPkgs = @("winget", "scoop", "choco","system") # Use the following option to specify custom package managers. # Create a function with that name as suffix, and which returns @@ -884,7 +884,7 @@ function info_pkgs { $wingetpkg = (winget list | Where-Object {$_.Trim("`n`r`t`b-\|/ ").Length -ne 0} | Measure-Object).Count - 1 if ($wingetpkg) { - $pkgs += "$wingetpkg (system)" + $pkgs += "$wingetpkg (winget)" } } @@ -908,6 +908,48 @@ function info_pkgs { } } + if ("system" -in $ShowPkgs) { + # Get all installed programs from the registry + $userPrograms = (Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall") -replace "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + $machinePrograms = (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") -replace "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + + # Create Variables + [hashtable]$programsHash = $null + [System.Collections.ArrayList]$programs = @() + + # If programs installed for entire machine is greater than programs installed for current user + if ($machinePrograms.Count -gt $userPrograms.Count){ + # Loop through all programs installed for entire machine + foreach($program in $machinePrograms){ + # Add each program to hash table and arraylist + [void]($programsHash += @{$program = $true}) + [void]($programs.Add($program)) + } + # Loop through all programs installed for current user + foreach($program in $userPrograms){ + # Checks hash table to prevent duplicates + if(!$programsHash[$program]){ + [void]($programs.Add($program)) + } + } + }else{ + # Loop through all programs installed for current user + foreach($program in $userPrograms){ + # Add each program to hash table and arraylist + [void]($programsHash += @{$program = $true}) + [void]($programs.Add($program)) + } + foreach($program in $machinePrograms){ + # Checks hash table to prevent duplicates + if(!$programsHash[$program]){ + [void]($programs.Add($program)) + } + } + } + + $pkgs += "$($programs.count) (system)" + } + foreach ($pkgitem in $CustomPkgs) { if (Test-Path Function:"info_pkg_$pkgitem") { $count = & "info_pkg_$pkgitem" From ee75d644dd385e3e4467836cf2de9e2b37d7d506 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Fri, 14 Oct 2022 13:14:35 -0500 Subject: [PATCH 3/5] Make "system" better - Missed two registry paths for 64-bit programs - Somehow tanking the errors is slightly faster than checking if $program had a value --- winfetch.ps1 | 68 +++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/winfetch.ps1 b/winfetch.ps1 index bb64e76..a5a30a4 100644 --- a/winfetch.ps1 +++ b/winfetch.ps1 @@ -910,43 +910,47 @@ function info_pkgs { if ("system" -in $ShowPkgs) { # Get all installed programs from the registry - $userPrograms = (Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall") -replace "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" - $machinePrograms = (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") -replace "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + if (Test-Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall") { + $userPrograms = ((Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty).DisplayName) + } + if (Test-Path "HKCU:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall") { + $userX64Programs = ((Get-ChildItem "HKCU:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty).DisplayName) + } + if (Test-Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") { + $machinePrograms = ((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty).DisplayName) + } + if (Test-Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall") { + $machineX64Programs = ((Get-ChildItem "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty).DisplayName) + } - # Create Variables - [hashtable]$programsHash = $null [System.Collections.ArrayList]$programs = @() - # If programs installed for entire machine is greater than programs installed for current user - if ($machinePrograms.Count -gt $userPrograms.Count){ - # Loop through all programs installed for entire machine - foreach($program in $machinePrograms){ - # Add each program to hash table and arraylist - [void]($programsHash += @{$program = $true}) - [void]($programs.Add($program)) - } - # Loop through all programs installed for current user - foreach($program in $userPrograms){ - # Checks hash table to prevent duplicates - if(!$programsHash[$program]){ - [void]($programs.Add($program)) - } - } - }else{ - # Loop through all programs installed for current user - foreach($program in $userPrograms){ - # Add each program to hash table and arraylist - [void]($programsHash += @{$program = $true}) - [void]($programs.Add($program)) - } - foreach($program in $machinePrograms){ - # Checks hash table to prevent duplicates - if(!$programsHash[$program]){ - [void]($programs.Add($program)) - } - } + # Save current state of ErrorActionPreference + $tempErrorActionPreference = $ErrorActionPreference + # Set ErrorActionPreference to not print errors as there are upcoming errors that are expected + $ErrorActionPreference = 'SilentlyContinue' + + # Interate through found programs and add them to the array + # Will error whenever it attempts to add a duplicate program which is leveraged to prevent duplicates + foreach($program in $machinePrograms) { + [void]($programs.Add($program.ToLower())) + } + + foreach($program in $userPrograms) { + [void]($programs.Add($program.ToLower())) + } + + foreach($program in $userX64Programs) { + [void]($programs.Add($program.ToLower())) + } + + foreach($program in $machineX64Programs) { + [void]($programs.Add($program.ToLower())) } + # Restore ErrorActionPreference to its original state + $ErrorActionPreference = $tempErrorActionPreference + $pkgs += "$($programs.count) (system)" } From e57cff58fa24bb72c8fc7485661c6b71329c8c89 Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Sun, 16 Oct 2022 12:05:02 -0500 Subject: [PATCH 4/5] Fix thing - Duplicate and null entries weren't being filtered out because I was using arraylists instead of hashtables - Filtering null entries via if-statements is now very slightly faster (1-3ms) --- winfetch.ps1 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/winfetch.ps1 b/winfetch.ps1 index a5a30a4..a6e8de2 100644 --- a/winfetch.ps1 +++ b/winfetch.ps1 @@ -923,29 +923,30 @@ function info_pkgs { $machineX64Programs = ((Get-ChildItem "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty).DisplayName) } - [System.Collections.ArrayList]$programs = @() + # Program list + [hashtable]$programs = @{} # Save current state of ErrorActionPreference $tempErrorActionPreference = $ErrorActionPreference # Set ErrorActionPreference to not print errors as there are upcoming errors that are expected $ErrorActionPreference = 'SilentlyContinue' - # Interate through found programs and add them to the array - # Will error whenever it attempts to add a duplicate program which is leveraged to prevent duplicates + # Interate through found programs and add them to the hashtable + # Hashtable is used because it doesn't allow duplicate entries, filtering them out by erroring foreach($program in $machinePrograms) { - [void]($programs.Add($program.ToLower())) + if($program){[void]($programs += @{$program = $true})} } foreach($program in $userPrograms) { - [void]($programs.Add($program.ToLower())) + if($program){[void]($programs += @{$program = $true})} } foreach($program in $userX64Programs) { - [void]($programs.Add($program.ToLower())) + if($program){[void]($programs += @{$program = $true})} } foreach($program in $machineX64Programs) { - [void]($programs.Add($program.ToLower())) + if($program){[void]($programs += @{$program = $true})} } # Restore ErrorActionPreference to its original state From b8576669da968d1509d065a472450f0980d5f4cb Mon Sep 17 00:00:00 2001 From: Carterpersall Date: Mon, 27 Feb 2023 09:40:12 -0600 Subject: [PATCH 5/5] Implement Winget Caching --- winfetch.ps1 | 55 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/winfetch.ps1 b/winfetch.ps1 index a6e8de2..4e10337 100644 --- a/winfetch.ps1 +++ b/winfetch.ps1 @@ -83,7 +83,8 @@ param( [ValidateSet("text", "bar", "textbar", "bartext")][string]$batterystyle = "text", [ValidateScript({$_ -gt 1 -and $_ -lt $Host.UI.RawUI.WindowSize.Width-1})][alias('w')][int]$imgwidth = 35, [array]$showdisks = @($env:SystemDrive), - [array]$showpkgs = @("scoop", "choco") + [array]$showpkgs = @("scoop", "choco", "system"), + [bool]$CacheWinget = $true ) if (-not ($IsWindows -or $PSVersionTable.PSVersion.Major -eq 5)) { @@ -155,9 +156,16 @@ $defaultConfig = @' # $ShowDisks = @("*") # Configure which package managers are shown -# disabling unused ones will improve speed # $ShowPkgs = @("winget", "scoop", "choco","system") +# Configure whether to cache winget's package count +# This will speed up the scripts execution time, but the returned package count might be outdated +$CacheWinget = $true + +# Winget Package Count Cache +# 0 Means no value is cached yet +$WingetCache = 0 + # Use the following option to specify custom package managers. # Create a function with that name as suffix, and which returns # the number of packages. Two examples are shown here: @@ -881,7 +889,46 @@ function info_pkgs { $pkgs = @() if ("winget" -in $ShowPkgs -and (Get-Command -Name winget -ErrorAction Ignore)) { - $wingetpkg = (winget list | Where-Object {$_.Trim("`n`r`t`b-\|/ ").Length -ne 0} | Measure-Object).Count - 1 + if ($CacheWinget) { + $wingetpkg = if ($null -ne $WingetCache) { + # Set the package count to the cached value + $WingetCache + } + + $scriptblock = { + param($configpath, $wingetpkg) + + # Get the number of packages + $newwingetpkg = (winget list | Where-Object {$_.Trim('`n`r`t`b-\\|/ ').Length -ne 0} | Measure-Object).Count - 1 + + # Get the text from the config file + $configtext = [System.IO.File]::ReadAllText($configpath) + + # Check if the cache variable exists in the config file + if ($null -ne $wingetpkg) { + # Replace the cached value with the new one + $configtext = $configtext -replace '(?<=\s*\$WingetCache\s*=\s*)\d+', $newwingetpkg + } else { + # If the cache variable doesn't exist, append it to the config file + $configtext += "`n# Winget Package Count Cache`n`$WingetCache = $newwingetpkg" + } + + # Overwrite the config file with the new text + $configtext | Out-File $configpath -Encoding utf8 -NoNewline + } + + # Check if the caching script already exists + if (-not (Test-Path "$env:TEMP\wingetcache.ps1")) { + # Create the caching script + $scriptblock | Out-File "$env:TEMP\wingetcache.ps1" + } + + # Start the caching script + Start-Process powershell -WindowStyle Hidden -ArgumentList "-NoLogo -NoProfile -File ""$env:TEMP\wingetcache.ps1"" ""$configpath"" $wingetpkg" + } else { + # Get the number of winget packages + $wingetpkg = (winget list | Where-Object {$_.Trim("`n`r`t`b-\|/ ").Length -ne 0} | Measure-Object).Count - 1 + } if ($wingetpkg) { $pkgs += "$wingetpkg (winget)" @@ -930,7 +977,7 @@ function info_pkgs { $tempErrorActionPreference = $ErrorActionPreference # Set ErrorActionPreference to not print errors as there are upcoming errors that are expected $ErrorActionPreference = 'SilentlyContinue' - + # Interate through found programs and add them to the hashtable # Hashtable is used because it doesn't allow duplicate entries, filtering them out by erroring foreach($program in $machinePrograms) {