2022-05-10 08:37:41 -05:00
<#
. NOTES
2022-05-17 10:59:06 -05:00
Author : @DeveloperDurp
GitHub : https : / / github . com / DeveloperDurp
Version 0.0 . 1
2022-05-10 08:37:41 -05:00
#>
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#region Header
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#region Load .Net framwork
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
[ Reflection.Assembly ] :: LoadWithPartialName ( " System.Windows.Forms " ) | Out-Null
Add-Type -AssemblyName System . Windows . Forms
Add-Type -AssemblyName PresentationFramework
[ System.Windows.Forms.Application ] :: EnableVisualStyles ( )
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#endregion Load .Net framework
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#Hiding Console Window
<#
Add-Type -Name Window -Namespace Console -MemberDefinition '
[ DllImport ( " Kernel32.dll " ) ]
public static extern IntPtr GetConsoleWindow ( ) ;
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
[ DllImport ( " user32.dll " ) ]
public static extern bool ShowWindow ( IntPtr hWnd , Int32 nCmdShow ) ;
'
$consolePtr = [ Console.Window ] :: GetConsoleWindow ( )
[ Console.Window ] :: ShowWindow ( $consolePtr , 0 ) > $Null
#>
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#endregion Header
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#region Functions
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#Instead of running the whole form in a run space I like to have it call the additional runspaces as
#I have found additional complexity when running forms outside of the main thread
function Invoke-Button {
Param ( [ string ] $Button )
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
Switch -Wildcard ( $Button ) {
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
" *InstallProgram_Button* " { Invoke-Runspace $InstallScript }
2022-05-10 08:18:13 -05:00
}
}
2022-05-17 10:59:06 -05:00
#You can call this function and pass a "powershell" script so that it can execute it inside a runspace.
#Anything executed with this function will be able to interact with the $global:sync variable
#Another neat feature you can do with this method is updating the form itself assuming you created the form objects inside the $sync variable
function Invoke-Runspace {
Param ( [ string ] $commands )
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
$Script = [ PowerShell ] :: Create ( ) . AddScript ( $commands )
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
$runspace = [ RunspaceFactory ] :: CreateRunspace ( )
$runspace . ApartmentState = " STA "
$runspace . ThreadOptions = " ReuseThread "
$runspace . Open ( )
$runspace . SessionStateProxy . SetVariable ( " sync " , $global:sync )
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
$Script . Runspace = $runspace
$Script . BeginInvoke ( )
2022-05-10 08:18:13 -05:00
}
2022-05-17 10:59:06 -05:00
#The prowershell gui scripts I build tend to be very daynamic in nature so I don't like to have a predefined layout like you do.
#This is one way for me to make sure things don't go too far down
Function Check-Space {
Param ( [ string ] $cords )
[ int ] $xint = ( $cords -split " ; " ) [ 0 ]
[ int ] $yint = ( $cords -split " ; " ) [ 1 ]
[ int ] $increment = ( $cords -split " ; " ) [ 2 ]
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
if ( $yint -gt 650 ) { Write-output " $( $xint + 225 ) " ; 10 }
if ( $yint -le 650 ) { Write-output " $xint ; $( $yint + $increment ) " }
2022-05-10 08:18:13 -05:00
}
2022-05-17 10:59:06 -05:00
#endregion functions
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#region Scripts
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
#This is what you pass to the Invoke-Runspace function. This can interact with the $sync variable and even make changes that the main form will pickup.
#IE I could say $global:sync["InstallProgram_Browsers-LibreWolf_Checkbox"].text = "LibreWolf Installed"
$InstallScript = {
$programstoinstall = @ ( )
$global:sync . keys | Where-Object { $_ -like " InstallProgram_*_Checkbox " } | ForEach-Object {
if ( $global:sync [ " $_ " ] . checked -eq $true ) {
$program = ( ( $_ -split " _ " ) [ 1 ] -split " - " ) [ 1 ]
$programstoinstall + = $program
2022-05-10 08:18:13 -05:00
}
}
2022-05-17 10:59:06 -05:00
[ System.Windows.MessageBox ] :: Show ( " I will install the following programs $programstoinstall " , 'Install Programs Button' , " OK " , " Info " )
2022-05-10 08:18:13 -05:00
}
2022-05-17 10:59:06 -05:00
#endregion Scripts
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
$version = " 0.0.1 "
$ToolName = " winutil "
$formwidth = 1170
$formHeight = 800
2022-05-10 08:18:13 -05:00
2022-05-17 10:59:06 -05:00
$InstallPrograms = @ (
" Browsers;Brave,Google Chrome,Un-Googled Chromium, Firefox,LibreWolf,Vivaldi "
" Communications;Discord,Hexchat,Matrix,Signal,Skype,Slack,Microsoft Teams,Zoom Video Conference "
" Development;Atom,Github Desktop,OpenJDK Java 8,OpenJDK Java 16,Oracle Java 18,Jetbrains Toolbox,NodeJS,NodeJS LTS,Python3,Sublime,Visual Studio Code 2022 Community,VS Code,VS Codium "
" Document;Adobe Reader DV,LibreOffice,Notepad++,Obsidian,Sumatra PDF "
" Games;Epic Games Launcher,GOG Galaxy,Steam "
" Pro Tools;Advanced IP Scanner,mRemoteNG,Putty,WinSCP,WireShark "
" Multimedia Tools; Audacity,Blander (3D Graphics),Eartumpet (Audio),Flameshot (Screenshots),Foobar2000 (Music Player),Gimp (Image Editor),Greenshot (Screenshots),HandBrake,ImageGlass (Image Viewer),Inkscape,Media Player Classic (Video Player),OBS Studio,ShareX (Screenshots),Spotify,VLC (Video Player),Voicemeeter (Audio) "
" Utilities;7-Zip,AnyDesk,AutoHotkey,Bitwarden,CPU-Z,Etcher USB Creator,Everything Search,GPU-Z,HWInfo,KeePassXC,MalwareBytes,NVCleanstall,Microsoft Powertoys,RevoUninstaller,Rufus Imager,TeamViewer,Translucent Taskbar,TreeSizeFree,WinDirStat,Windows Terminal "
2022-05-10 08:18:13 -05:00
)
2022-05-17 10:59:06 -05:00
$tabs = @ (
" Install "
" Tweaks "
" Config "
" Updates "
" Help "
2022-05-10 08:18:13 -05:00
)
2022-05-17 10:59:06 -05:00
$global:sync = [ Hashtable ] :: Synchronized ( @ { } )
#region Form
$Form = New-Object system . Windows . Forms . Form
$Form . text = " $toolname $Version "
$form . AutoScroll = $True
$form . width = $formwidth
$form . Height = $formHeight
$Form . FormBorderStyle = 'Fixed3D'
$Form . MaximizeBox = $false
$Form . Add_FormClosing ( {
Get-Process -Id $pid | Stop-Process
} )
#For adding in an icon image
#$iconBase64 = ''
#$iconBytes = [Convert]::FromBase64String($iconBase64)
#$stream = New-Object IO.MemoryStream($iconBytes, 0, $iconBytes.Length)
#$stream.Write($iconBytes, 0, $iconBytes.Length);
#$Form.Icon = [System.Drawing.Icon]::FromHandle((New-Object System.Drawing.Bitmap -Argument $stream).GetHIcon())
#endregion Form
#region Tab Control
$tabcontrol = New-Object 'System.Windows.Forms.TabControl'
$tabcontrol . Alignment = 'Top'
$tabcontrol . Location = '0,0'
$tabcontrol . Multiline = $True
$tabcontrol . Name = 'tabcontrol'
$tabcontrol . SelectedIndex = 0
$tabcontrol . width = $formwidth
$tabcontrol . Height = $ ( $formHeight - 35 )
$tabcontrol . Anchor = [ System.Windows.Forms.AnchorStyles ] :: Bottom -bor [ System.Windows.Forms.AnchorStyles ] :: Right -bor [ System.Windows.Forms.AnchorStyles ] :: Top -bor [ System.Windows.Forms.AnchorStyles ] :: Left
$tabcontrol . TabIndex = 0
$Form . Controls . Add ( $tabcontrol )
#endregion Tab Control
#region Main Page
foreach ( $tab in $tabs ) {
$page = New-Object 'System.Windows.Forms.TabPage'
$page . name = " $tab "
$page . text = " $tab "
$tabcontrol . Controls . Add ( $page )
}
#Since I don't use an xaml file to create the gui (not sure how compatable that method is with this script as I have never used it) I create a loop to build everything.
#You could do the same for the rest of the tabs in a similar fashion to this one.
#region Install Tab
$x = 5
$y = 10
foreach ( $InstallProgram in $InstallPrograms ) {
$group = ( $InstallProgram -split " ; " ) [ 0 ]
$programs = ( $InstallProgram -split " ; " ) [ 1 ] -split " , "
$Label = New-Object Windows . Forms . Label
$Label . Name = " $group "
$Label . Location = New-Object System . Drawing . Point ( $x , $y )
$Label . Font = 'Microsoft Sans Serif,15'
$Label . Text = " $group "
$Label . AutoSize = $true
$tabcontrol . controls [ " Install " ] . Controls . Add ( $Label )
$space = ( Check-Space " $x ; $y ;40 " ) -split " ; "
$x = $space [ 0 ]
$y = $space [ 1 ]
foreach ( $program in $programs ) {
#The key here is adding the object to the $sync variable, this what allows powershell to interact with it while inside a runspace.
#IE $tabcontrol.controls["Install"] is not modifiable but $global:sync["InstallProgram_Browsers-LibreWolf_Checkbox"] is
$object = New-Object Windows . Forms . Checkbox
$object . Name = " InstallProgram_ $group - $( $program -replace " " , " _ " ) _Checkbox "
$object . Font = 'Microsoft Sans Serif,8'
$object . Location = New-Object System . Drawing . Point ( $x , $y )
$object . Size = " 225,20 "
$object . text = " $program "
$object . checked = $false
$global:sync [ " $( $object . name ) " ] = $object
$tabcontrol . Controls [ " Install " ] . Controls . Add ( $global:sync [ " $( $object . name ) " ] )
$space = ( Check-Space " $x ; $y ;20 " ) -split " ; "
$x = $space [ 0 ]
$y = $space [ 1 ]
}
$y = [ int ] $y + 10
}
$space = ( Check-Space " $x ;9000;20 " ) -split " ; "
$x = $space [ 0 ]
$y = $space [ 1 ]
$object = New-Object 'System.Windows.Forms.Button'
$object . name = " InstallProgram_Button "
$object . Location = New-Object System . Drawing . Point ( $x , $y )
$object . Font = 'Microsoft Sans Serif,10'
$object . Size = " 200,25 "
$object . TextAlign = 'MiddleCenter'
$object . text = " Install Programs "
$object . Add_Click ( {
#This took me a long time to figure out as my other scripts would create buttons dynamically. This will get the name of the button that you clicked
#then pass it to the Invoke-Button function above.
[ System.Object ] $Sender = $args [ 0 ]
Invoke-Button $Sender . name
} )
$tabcontrol . controls [ " Install " ] . Controls . Add ( $object )
#endregion Install Tab
#region Help Page
$Label = New-Object Windows . Forms . Label
$Label . Name = " Help_Page_Label "
$Label . Location = New-Object System . Drawing . Point ( 5 , 10 )
$Label . Font = 'Microsoft Sans Serif,15'
$Label . Text = " Welcome to the Help Page "
$Label . AutoSize = $true
$tabcontrol . controls [ " help " ] . Controls . Add ( $Label )
#endregion Help Page
#endregion Main Page
[ Windows.Forms.Application ] :: Run ( $form )