mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 17:41:14 +10:00
Speed up runspace and tab initialization (#4793)
* Add startup performance tracing * Lazy initialize non-default tabs * Render install app entries incrementally * Defer and cache toggle status checks * Clean up runspace invocation ownership * Defer GUI runspace pool startup * Defer status taskbar asset rendering * Record final speed verification * Fix deferred install render timer callback * Add dispatcher smoke coverage for install rendering * Replace install render timer with dispatcher callbacks * Gate performance tracing behind compile switch * Clean up analyzer warnings in speed changes * Speed up runspace and tab initialization
This commit is contained in:
+20
-60
@@ -29,39 +29,6 @@ public enum PackageManagers
|
||||
}
|
||||
"@
|
||||
|
||||
# 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
|
||||
|
||||
# Create a new session state for parsing variables into our runspace
|
||||
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
|
||||
$offlineVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_OFFLINE',$PARAM_OFFLINE,$Null
|
||||
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
|
||||
|
||||
# Add the variable to the session state
|
||||
$InitialSessionState.Variables.Add($hashVars)
|
||||
$InitialSessionState.Variables.Add($offlineVar)
|
||||
|
||||
# Get every private function and add them to the session state
|
||||
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
|
||||
foreach ($function in $functions) {
|
||||
$functionDefinition = Get-Content function:\$($function.name)
|
||||
$functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $($function.name), $functionDefinition
|
||||
|
||||
$initialSessionState.Commands.Add($functionEntry)
|
||||
}
|
||||
|
||||
# Create the runspace pool
|
||||
$sync.runspace = [runspacefactory]::CreateRunspacePool(
|
||||
1, # Minimum thread count
|
||||
$maxthreads, # Maximum thread count
|
||||
$InitialSessionState, # Initial session state
|
||||
$Host # Machine to create runspaces on
|
||||
)
|
||||
|
||||
# Open the RunspacePool instance
|
||||
$sync.runspace.Open()
|
||||
|
||||
# Create classes for different exceptions
|
||||
|
||||
class WingetFailedInstall : Exception {
|
||||
@@ -90,10 +57,14 @@ $sync.configs.appxHashtable = @{}
|
||||
$sync.configs.appx.PSObject.Properties | ForEach-Object {
|
||||
$sync.configs.appxHashtable[$_.Name] = $_.Value
|
||||
}
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Config hashtables initialized"
|
||||
|
||||
Set-Preferences
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Preferences loaded"
|
||||
|
||||
if ($Preset) {
|
||||
Initialize-WinUtilRunspacePool | Out-Null
|
||||
|
||||
# Selects the tweaks from $Preset varible
|
||||
Update-WinUtilSelections -flatJson $sync.configs.preset.$Preset
|
||||
|
||||
@@ -101,21 +72,21 @@ if ($Preset) {
|
||||
Invoke-WinUtilAutoRun
|
||||
|
||||
# Cleanup and exit
|
||||
$sync.runspace.Dispose()
|
||||
$sync.runspace.Close()
|
||||
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
|
||||
$sync.runspace.Dispose()
|
||||
$sync.runspace.Close()
|
||||
Close-WinUtilRunspacePool
|
||||
[System.GC]::Collect()
|
||||
Stop-Transcript
|
||||
return
|
||||
@@ -130,6 +101,7 @@ $reader = (New-Object System.Xml.XmlNodeReader $xaml)
|
||||
try {
|
||||
$sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader )
|
||||
$readerOperationSuccessful = $true
|
||||
Write-WinUtilPerformanceCheckpoint -Name "XAML loaded"
|
||||
} 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
|
||||
@@ -144,8 +116,7 @@ try {
|
||||
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
|
||||
$sync.runspace.Dispose()
|
||||
$sync.runspace.Close()
|
||||
Close-WinUtilRunspacePool
|
||||
[System.GC]::Collect()
|
||||
exit 1
|
||||
}
|
||||
@@ -179,19 +150,12 @@ $sync.Form.Add_Loaded({
|
||||
})
|
||||
|
||||
Invoke-WinutilThemeChange -theme $sync.preferences.theme
|
||||
Write-WinUtilPerformanceCheckpoint -Name "Theme applied"
|
||||
|
||||
|
||||
# Now call the function with the final merged config
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
|
||||
Initialize-WPFUI -targetGridName "appscategory"
|
||||
|
||||
Initialize-WPFUI -targetGridName "appspanel"
|
||||
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
|
||||
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
|
||||
|
||||
Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2
|
||||
# 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
|
||||
@@ -257,8 +221,8 @@ Set-WinUtilTaskbaritem -state "None"
|
||||
$sync["Form"].title = $sync["Form"].title + " " + $sync.version
|
||||
# Set the commands that will run when the form is closed
|
||||
$sync["Form"].Add_Closing({
|
||||
$sync.runspace.Dispose()
|
||||
$sync.runspace.Close()
|
||||
Stop-WinUtilPerformanceTrace -Name "Window closing"
|
||||
Close-WinUtilRunspacePool
|
||||
[System.GC]::Collect()
|
||||
})
|
||||
|
||||
@@ -326,6 +290,7 @@ $sync["Form"].Add_Deactivated({
|
||||
})
|
||||
|
||||
$sync["Form"].Add_ContentRendered({
|
||||
Write-WinUtilPerformanceCheckpoint -Name "First content rendered"
|
||||
# Load the Windows Forms assembly
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
$primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen
|
||||
@@ -374,6 +339,8 @@ $sync["Form"].Add_ContentRendered({
|
||||
}
|
||||
|
||||
$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
|
||||
@@ -418,10 +385,7 @@ $sync["Form"].Add_Loaded({
|
||||
|
||||
$NavLogoPanel = $sync["Form"].FindName("NavLogoPanel")
|
||||
$NavLogoPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) | Out-Null
|
||||
|
||||
$sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render)
|
||||
$sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render)
|
||||
$sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render)
|
||||
Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $true -IncludeStatusAssets $false
|
||||
|
||||
Set-WinUtilTaskbaritem -overlay "logo"
|
||||
|
||||
@@ -514,10 +478,6 @@ $sync["FontScalingApplyButton"].Add_Click({
|
||||
|
||||
# ── Win11ISO Tab button handlers ──────────────────────────────────────────────
|
||||
|
||||
$sync["WPFTab5BT"].Add_Click({
|
||||
$sync["Form"].Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null
|
||||
})
|
||||
|
||||
$sync["WPFWin11ISOBrowseButton"].Add_Click({
|
||||
Invoke-WinUtilISOBrowse
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user