Skip to content

Commit 916fadf

Browse files
committed
Fixed startup performance and null reference bugs
1 parent 3a7232c commit 916fadf

2 files changed

Lines changed: 33 additions & 14 deletions

File tree

Microsoft.PowerShell_profile.ps1

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ function file {
955955
$bytes = New-Object byte[] $readLen
956956
[void]$stream.Read($bytes, 0, $readLen)
957957
}
958-
finally { $stream.Close() }
958+
finally { $stream.Dispose() }
959959

960960
$hex = -join ($bytes[0..([Math]::Min(3, $readLen - 1))] | ForEach-Object { '{0:X2}' -f $_ })
961961
$result = $null
@@ -1483,6 +1483,7 @@ function svc {
14831483
[int]$Count = 25,
14841484
[switch]$Live
14851485
)
1486+
$bootTime = Get-SystemBootTime
14861487
do {
14871488
if ($Live) { Clear-Host }
14881489
try { $os = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop }
@@ -1492,7 +1493,7 @@ function svc {
14921493
$memPct = [math]::Round($usedMem / $totalMem * 100)
14931494
$cpuLoad = try { [math]::Round((Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Average).Average) } catch { 0 }
14941495
$procCount = @(Get-Process).Count
1495-
$up = (Get-Date) - (Get-SystemBootTime)
1496+
$up = (Get-Date) - $bootTime
14961497
$upStr = '{0}d {1}h {2}m' -f $up.Days, $up.Hours, $up.Minutes
14971498
Write-Host ''
14981499
Write-Host (' CPU: {0}% | Mem: {1}/{2} GB ({3}%) | Procs: {4} | Up: {5}' -f $cpuLoad, $usedMem, $totalMem, $memPct, $procCount, $upStr) -ForegroundColor Cyan
@@ -2111,7 +2112,12 @@ function tlscert {
21112112
)
21122113
$tcp = $null; $ssl = $null; $cert = $null
21132114
try {
2114-
$tcp = New-Object System.Net.Sockets.TcpClient($Domain, $Port)
2115+
$tcp = New-Object System.Net.Sockets.TcpClient
2116+
$async = $tcp.BeginConnect($Domain, $Port, $null, $null)
2117+
if (-not $async.AsyncWaitHandle.WaitOne(5000)) {
2118+
throw "Connection to ${Domain}:${Port} timed out after 5 seconds"
2119+
}
2120+
$tcp.EndConnect($async)
21152121
$ssl = New-Object System.Net.Security.SslStream($tcp.GetStream(), $false, {$true})
21162122
$ssl.AuthenticateAsClient($Domain)
21172123
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($ssl.RemoteCertificate)
@@ -2452,20 +2458,27 @@ if ($isInteractive) {
24522458
}
24532459
if ($localThemePath -and (Test-Path $localThemePath)) {
24542460
# Cache the OMP init script so we don't shell out every startup
2455-
# Header tracks both OMP version AND theme path so a theme switch invalidates the cache
2461+
# Header tracks both OMP version AND theme path so a theme switch invalidates the cache.
2462+
# PERF: Defer `oh-my-posh version` (~2-3s) until we know the cache is missing/stale.
2463+
# When the cache exists, validate using only the theme path portion of the header
2464+
# (version changes are handled by Update-Tools which deletes the cache on upgrade).
24562465
$ompCachePath = Join-Path $cacheDir "omp-init.ps1"
2457-
$ompVersion = try { ((oh-my-posh version) | Out-String).Trim() } catch { 'unknown' }
2458-
$ompCacheHeader = '# OMP_CACHE: {0} | {1}' -f $ompVersion, $localThemePath
24592466
$cacheValid = $false
24602467
if (Test-Path $ompCachePath) {
24612468
$fileSize = (Get-Item $ompCachePath).Length
24622469
if ($fileSize -gt 0) {
24632470
$cacheContent = Get-Content $ompCachePath -First 1
2464-
if ($cacheContent -eq $ompCacheHeader) { $cacheValid = $true }
2471+
# Fast check: just verify the header references the correct theme path
2472+
if ($cacheContent -match '^# OMP_CACHE: .+ \| ' -and $cacheContent.EndsWith($localThemePath)) {
2473+
$cacheValid = $true
2474+
}
24652475
}
24662476
if (-not $cacheValid) { Remove-Item $ompCachePath -Force -ErrorAction SilentlyContinue }
24672477
}
24682478
if (-not $cacheValid) {
2479+
# Only pay the cost of `oh-my-posh version` when we need to regenerate the cache
2480+
$ompVersion = try { ((oh-my-posh version) | Out-String).Trim() } catch { 'unknown' }
2481+
$ompCacheHeader = '# OMP_CACHE: {0} | {1}' -f $ompVersion, $localThemePath
24692482
$initScript = oh-my-posh init pwsh --config $localThemePath
24702483
if ($initScript) {
24712484
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
@@ -2481,6 +2494,8 @@ if ($isInteractive) {
24812494
catch {
24822495
Remove-Item $ompCachePath -Force -ErrorAction SilentlyContinue
24832496
try {
2497+
$ompVersion = try { ((oh-my-posh version) | Out-String).Trim() } catch { 'unknown' }
2498+
$ompCacheHeader = '# OMP_CACHE: {0} | {1}' -f $ompVersion, $localThemePath
24842499
$initScript = oh-my-posh init pwsh --config $localThemePath
24852500
if ($initScript) {
24862501
$utf8NoBom = [System.Text.UTF8Encoding]::new($false)
@@ -2506,17 +2521,19 @@ if ($isInteractive) {
25062521
if ($isInteractive) {
25072522
if (Get-Command zoxide -ErrorAction SilentlyContinue) {
25082523
$zoxideCachePath = Join-Path $cacheDir "zoxide-init.ps1"
2509-
$zoxideVersion = try { ((zoxide --version 2>$null) | Out-String).Trim() } catch { 'unknown' }
2524+
# PERF: Defer `zoxide --version` (~1s) until cache is missing/stale.
2525+
# When cache exists and is non-empty, trust it (Update-Tools deletes cache on upgrade).
25102526
$cacheValid = $false
25112527
if (Test-Path $zoxideCachePath) {
25122528
$fileSize = (Get-Item $zoxideCachePath).Length
25132529
if ($fileSize -gt 0) {
25142530
$cacheContent = Get-Content $zoxideCachePath -First 1
2515-
if ($cacheContent -eq "# ZOXIDE_CACHE_VERSION: $zoxideVersion") { $cacheValid = $true }
2531+
if ($cacheContent -match '^# ZOXIDE_CACHE_VERSION: .+') { $cacheValid = $true }
25162532
}
25172533
if (-not $cacheValid) { Remove-Item $zoxideCachePath -Force -ErrorAction SilentlyContinue }
25182534
}
25192535
if (-not $cacheValid) {
2536+
$zoxideVersion = try { ((zoxide --version 2>$null) | Out-String).Trim() } catch { 'unknown' }
25202537
$initScript = (zoxide init --cmd z powershell | Out-String)
25212538
if ($initScript) {
25222539
$zoxideHeader = "# ZOXIDE_CACHE_VERSION: $zoxideVersion"
@@ -2533,6 +2550,7 @@ if ($isInteractive) {
25332550
catch {
25342551
Remove-Item $zoxideCachePath -Force -ErrorAction SilentlyContinue
25352552
try {
2553+
$zoxideVersion = try { ((zoxide --version 2>$null) | Out-String).Trim() } catch { 'unknown' }
25362554
$initScript = (zoxide init --cmd z powershell | Out-String)
25372555
if ($initScript) {
25382556
$zoxideHeader = "# ZOXIDE_CACHE_VERSION: $zoxideVersion"

setup.ps1

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ function Install-NerdFonts {
116116
}
117117
}
118118
# CopyHere is async - wait for fonts to arrive before deleting source
119+
$pending = $null
119120
if ($copied -gt 0) {
120121
$timeout = 60; $elapsed = 0
121122
while ($elapsed -lt $timeout) {
@@ -517,12 +518,12 @@ function Install-WingetPackage {
517518
# OMP Install
518519
Write-Host "[3/10] Oh My Posh" -ForegroundColor Cyan
519520
$ompInstalled = Install-WingetPackage -Name "Oh My Posh" -Id "JanDeDobbeleer.OhMyPosh"
520-
if ($profileConfig -and $profileConfig.theme.name -and $profileConfig.theme.url) {
521+
if ($profileConfig -and $profileConfig.theme -and $profileConfig.theme.name -and $profileConfig.theme.url) {
521522
$themeInstalled = Install-OhMyPoshTheme -ThemeName $profileConfig.theme.name -ThemeUrl $profileConfig.theme.url
522523
}
523524
else {
524525
$reason = if (-not $profileConfig) { "theme.json missing" }
525-
elseif (-not $profileConfig.theme.name) { "theme name missing" }
526+
elseif (-not $profileConfig.theme -or -not $profileConfig.theme.name) { "theme name missing" }
526527
else { "theme URL missing" }
527528
Write-Host " Skipped theme download ($reason)." -ForegroundColor Yellow
528529
$themeInstalled = $false
@@ -643,9 +644,9 @@ if (Test-Path $wtSettingsPath) {
643644

644645
# Explicit -ColorScheme param wins over config
645646
$cfgColorScheme = if ($PSBoundParameters.ContainsKey('ColorScheme')) { $ColorScheme }
646-
elseif ($profileConfig -and $profileConfig.windowsTerminal.colorScheme) { $profileConfig.windowsTerminal.colorScheme }
647+
elseif ($profileConfig -and $profileConfig.windowsTerminal -and $profileConfig.windowsTerminal.colorScheme) { $profileConfig.windowsTerminal.colorScheme }
647648
else { $null }
648-
$cfgCursorColor = if ($profileConfig -and $profileConfig.windowsTerminal.cursorColor) { $profileConfig.windowsTerminal.cursorColor } else { $null }
649+
$cfgCursorColor = if ($profileConfig -and $profileConfig.windowsTerminal -and $profileConfig.windowsTerminal.cursorColor) { $profileConfig.windowsTerminal.cursorColor } else { $null }
649650
if ($cfgColorScheme) {
650651
$defaults | Add-Member -NotePropertyName "colorScheme" -NotePropertyValue $cfgColorScheme -Force
651652
}
@@ -654,7 +655,7 @@ if (Test-Path $wtSettingsPath) {
654655
}
655656

656657
# Upsert color scheme from config
657-
if ($profileConfig -and $profileConfig.windowsTerminal.scheme) {
658+
if ($profileConfig -and $profileConfig.windowsTerminal -and $profileConfig.windowsTerminal.scheme) {
658659
$schemeDef = [PSCustomObject]$profileConfig.windowsTerminal.scheme
659660
if (-not $wt.schemes) {
660661
$wt | Add-Member -NotePropertyName "schemes" -NotePropertyValue @() -Force

0 commit comments

Comments
 (0)