Skip to content

Speed Up info_pkgs #161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 100 additions & 8 deletions winfetch.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ param(
[ValidateScript({$_ -gt 1 -and $_ -lt $Host.UI.RawUI.WindowSize.Width-1})][alias('w')][int]$imgwidth = 35,
[ValidateScript({$_ -ge 0 -and $_ -le 255})][alias('t')][int]$alphathreshold = 50,
[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)) {
Expand Down Expand Up @@ -161,8 +162,15 @@ $defaultConfig = @'
# $ShowDisks = @("*")

# Configure which package managers are shown
# disabling unused ones will improve speed
# $ShowPkgs = @("winget", "scoop", "choco")
# $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
Expand Down Expand Up @@ -864,17 +872,54 @@ 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 (system)"
$pkgs += "$wingetpkg (winget)"
}
}

if ("choco" -in $ShowPkgs -and (Get-Command -Name choco -ErrorAction Ignore)) {
$chocopkg = Invoke-Expression $(
"(& choco list" + $(if([version](& choco --version).Split('-')[0]`
-lt [version]'2.0.0'){" --local-only"}) + ")[-1].Split(' ')[0] - 1")
$chocopkg = (Get-ChildItem -Path "$env:ChocolateyInstall\lib").count - 1

if ($chocopkg) {
$pkgs += "$chocopkg (choco)"
Expand All @@ -893,6 +938,53 @@ function info_pkgs {
}
}

if ("system" -in $ShowPkgs) {
# Get all installed programs from the registry
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)
}

# 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 hashtable
# Hashtable is used because it doesn't allow duplicate entries, filtering them out by erroring
foreach($program in $machinePrograms) {
if($program){[void]($programs += @{$program = $true})}
}

foreach($program in $userPrograms) {
if($program){[void]($programs += @{$program = $true})}
}

foreach($program in $userX64Programs) {
if($program){[void]($programs += @{$program = $true})}
}

foreach($program in $machineX64Programs) {
if($program){[void]($programs += @{$program = $true})}
}

# Restore ErrorActionPreference to its original state
$ErrorActionPreference = $tempErrorActionPreference

$pkgs += "$($programs.count) (system)"
}

foreach ($pkgitem in $CustomPkgs) {
if (Test-Path Function:"info_pkg_$pkgitem") {
$count = & "info_pkg_$pkgitem"
Expand Down