2023-07-27 16:06:41 -05:00
# SPDX-License-Identifier: MIT
2023-05-09 13:14:27 -05:00
#Configure max thread count for RunspacePool.
$maxthreads = [ int ] $env:NUMBER_OF_PROCESSORS
#Create a new session state for parsing variables ie hashtable into our runspace.
$hashVars = New-object System . Management . Automation . Runspaces . SessionStateVariableEntry -ArgumentList 'sync' , $sync , $Null
$InitialSessionState = [ System.Management.Automation.Runspaces.InitialSessionState ] :: CreateDefault ( )
#Add the variable to the RunspacePool sessionstate
$InitialSessionState . Variables . Add ( $hashVars )
#Add functions
$functions = Get-ChildItem function : \ | Where-Object { $_ . name -like " *winutil* " -or $_ . name -like " *WPF* " }
foreach ( $function in $functions ) {
$functionDefinition = Get-Content function : \ $ ( $function . name )
$functionEntry = New-Object System . Management . Automation . Runspaces . SessionStateFunctionEntry -ArgumentList $ ( $function . name ) , $functionDefinition
2023-10-04 10:08:10 -05:00
2023-05-09 13:14:27 -05:00
# And add it to the iss object
$initialSessionState . Commands . Add ( $functionEntry )
}
#Create our runspace pool. We are entering three parameters here min thread count, max thread count and host machine of where these runspaces should be made.
$sync . runspace = [ runspacefactory ] :: CreateRunspacePool ( 1 , $maxthreads , $InitialSessionState , $Host )
#Open a RunspacePool instance.
$sync . runspace . Open ( )
2023-03-07 14:28:00 -06:00
#region exception classes
class WingetFailedInstall : Exception {
[ string ] $additionalData
WingetFailedInstall ( $Message ) : base ( $Message ) { }
}
2023-10-04 10:08:10 -05:00
2023-03-07 14:28:00 -06:00
class ChocoFailedInstall : Exception {
[ string ] $additionalData
ChocoFailedInstall ( $Message ) : base ( $Message ) { }
}
class GenericException : Exception {
[ string ] $additionalData
GenericException ( $Message ) : base ( $Message ) { }
}
2023-10-04 10:08:10 -05:00
2023-03-07 14:28:00 -06:00
#endregion exception classes
$inputXML = $inputXML -replace 'mc:Ignorable="d"' , '' -replace " x:N " , 'N' -replace '^<Win.*' , '<Window'
2023-07-27 16:06:41 -05:00
if ( ( Get-WinUtilToggleStatus WPFToggleDarkMode ) -eq $True ) {
$ctttheme = 'Matrix'
}
Else {
$ctttheme = 'Classic'
}
2023-07-13 15:46:00 -05:00
$inputXML = Set-WinUtilUITheme -inputXML $inputXML -themeName $ctttheme
2023-03-07 14:28:00 -06:00
[ void][System.Reflection.Assembly ] :: LoadWithPartialName ( 'presentationframework' )
[ xml ] $XAML = $inputXML
#Read XAML
$reader = ( New-Object System . Xml . XmlNodeReader $xaml )
2023-05-09 13:14:27 -05:00
try { $sync [ " Form " ] = [ Windows.Markup.XamlReader ] :: Load ( $reader ) }
2023-03-07 14:28:00 -06:00
catch [ System.Management.Automation.MethodInvocationException ] {
Write-Warning " We ran into a problem with the XAML code. Check the syntax for this control... "
Write-Host $error [ 0 ] . Exception . Message -ForegroundColor Red
If ( $error [ 0 ] . Exception . Message -like " *button* " ) {
write-warning " Ensure your <button in the `$ inputXML does NOT have a Click=ButtonClick property. PS can't handle this `n `n `n `n "
}
}
catch {
# If it broke some other way <img draggable="false" role="img" class="emoji" alt="😀" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/1f600.svg">
Write-Host " Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed. "
}
#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
2023-05-09 13:14:27 -05:00
$xaml . SelectNodes ( " //*[@Name] " ) | ForEach-Object { $sync [ " $( " $( $psitem . Name ) " ) " ] = $sync [ " Form " ] . FindName ( $psitem . Name ) }
2023-03-07 14:28:00 -06:00
2023-05-09 13:14:27 -05:00
$sync . keys | ForEach-Object {
if ( $sync . $psitem ) {
if ( $ ( $sync [ " $psitem " ] . GetType ( ) | Select-Object -ExpandProperty Name ) -eq " Button " ) {
$sync [ " $psitem " ] . Add_Click ( {
[ System.Object ] $Sender = $args [ 0 ]
Invoke-WPFButton $Sender . name
} )
}
}
2023-03-07 14:28:00 -06:00
}
2023-05-09 13:14:27 -05:00
2023-07-27 16:06:41 -05:00
$sync . keys | ForEach-Object {
if ( $sync . $psitem ) {
if (
$ ( $sync [ " $psitem " ] . GetType ( ) | Select-Object -ExpandProperty Name ) -eq " CheckBox " `
-and $sync [ " $psitem " ] . Name -like " WPFToggle* "
) {
$sync [ " $psitem " ] . IsChecked = Get-WinUtilToggleStatus $sync [ " $psitem " ] . Name
$sync [ " $psitem " ] . Add_Click ( {
[ System.Object ] $Sender = $args [ 0 ]
Invoke-WPFToggle $Sender . name
} )
}
}
}
2023-03-07 14:28:00 -06:00
#===========================================================================
# Setup background config
#===========================================================================
#Load information in the background
Invoke-WPFRunspace -ScriptBlock {
$sync . ConfigLoaded = $False
$sync . ComputerInfo = Get-ComputerInfo
$sync . ConfigLoaded = $True
} | Out-Null
#===========================================================================
# Shows the form
#===========================================================================
Invoke-WPFFormVariables
try {
Install-WinUtilChoco
}
Catch [ ChocoFailedInstall ] {
Write-Host " =========================================== "
Write-Host " -- Chocolatey failed to install --- "
Write-Host " =========================================== "
}
2023-05-09 13:14:27 -05:00
$sync [ " Form " ] . title = $sync [ " Form " ] . title + " " + $sync . version
$sync [ " Form " ] . Add_Closing ( {
$sync . runspace . Dispose ( )
$sync . runspace . Close ( )
[ System.GC ] :: Collect ( )
} )
$sync [ " Form " ] . ShowDialog ( ) | out-null
2023-03-07 14:28:00 -06:00
Stop-Transcript