Formularis amb Powershell
Fa uns dies, buscant scripts útils de powershell per veure si es podia aprofitar alguna cosa per la feina, em vaig trobar que parlaven de formularis amb powershell ¿?
Sembla que hi ha integrat un sistema per a generar formularis i fer una interfície molt més visual i agradable en el cas que sigui necessari. L’exemple feia aparèixer un formulari indicant que es procedia a reiniciar l’ordinador en cas que no es digués res en uns segons, en cas contrari es podia retrassar el reinici 5 minuts per poder guardar la feina i que no afectés a l’usuari.
Però com es generen aquests formularis? Picant codi i afegint-lo a la capçalera del nostre script, però els bons senyors de POSHGUI (https://poshgui.com/) ens ofereixen una funció més WYSIWYG per tant desenvolupar millor aquests formularis. Un cop acabat, podem indicar quins funcions cridaran alguns events (per exemple click a un botó) i poder escriure codi. Al acabar podem copiar al portapapers, guardar en TXT o en PS1 la feina feta. Per descomptat podem guardar de forma privada o pública la nostra feina a la mateixa web.
Per provar una mica com quedava el formulari, he decidit portar un programa senzill que intercanvia cada 2 bytes entre ells, aquest tipus de programa s’el coneix com a Byte Swapping i es fa servir en les repros de megadrive, us en parlo una mica en uns tallers de youtube (https://youtu.be/oIE5eXIrmEE) .
No parlaré de com funciona POSHGUI perquè és relativament senzill captar com funciona. Jo personalment el que he fet és crear el formulari, indicar les funcions que s’executen al fer click als botons i la resta l’he acabat amb un IDE/Editor qualsevol.
<# This form was created using POSHGUI.com a free online gui designer for PowerShell
.NAME
Swap Byte
Code by Kamencesc // DigichafarFan // Bonus
#>
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = '406,210'
$Form.text = "Swap Byte (Powershell ed)"
$Form.TopMost = $false
$Label1 = New-Object system.Windows.Forms.Label
$Label1.text = "Path:"
$Label1.AutoSize = $true
$Label1.width = 25
$Label1.height = 10
$Label1.location = New-Object System.Drawing.Point(14,30)
$Label1.Font = 'Microsoft Sans Serif,10'
$sourcePath = New-Object system.Windows.Forms.TextBox
$sourcePath.multiline = $false
$sourcePath.width = 280
$sourcePath.height = 20
$sourcePath.location = New-Object System.Drawing.Point(51,27)
$sourcePath.Font = 'Microsoft Sans Serif,10'
$Button1 = New-Object system.Windows.Forms.Button
$Button1.text = "..."
$Button1.width = 33
$Button1.height = 30
$Button1.location = New-Object System.Drawing.Point(340,21)
$Button1.Font = 'Microsoft Sans Serif,10'
$Groupbox1 = New-Object system.Windows.Forms.Groupbox
$Groupbox1.height = 64
$Groupbox1.width = 380
$Groupbox1.text = "Source file"
$Groupbox1.location = New-Object System.Drawing.Point(11,12)
$Groupbox2 = New-Object system.Windows.Forms.Groupbox
$Groupbox2.height = 64
$Groupbox2.width = 380
$Groupbox2.text = "Destination file"
$Groupbox2.location = New-Object System.Drawing.Point(11,89)
$Label2 = New-Object system.Windows.Forms.Label
$Label2.text = "Path:"
$Label2.AutoSize = $true
$Label2.width = 25
$Label2.height = 10
$Label2.location = New-Object System.Drawing.Point(14,30)
$Label2.Font = 'Microsoft Sans Serif,10'
$Button2 = New-Object system.Windows.Forms.Button
$Button2.text = "..."
$Button2.width = 33
$Button2.height = 30
$Button2.location = New-Object System.Drawing.Point(340,21)
$Button2.Font = 'Microsoft Sans Serif,10'
$destinationPath = New-Object system.Windows.Forms.TextBox
$destinationPath.multiline = $false
$destinationPath.width = 280
$destinationPath.height = 20
$destinationPath.location = New-Object System.Drawing.Point(51,27)
$destinationPath.Font = 'Microsoft Sans Serif,10'
$Button3 = New-Object system.Windows.Forms.Button
$Button3.text = "Go"
$Button3.width = 60
$Button3.height = 30
$Button3.location = New-Object System.Drawing.Point(331,165)
$Button3.Font = 'Microsoft Sans Serif,10'
$ProgressBar1 = New-Object system.Windows.Forms.ProgressBar
$ProgressBar1.width = 300
$ProgressBar1.height = 30
$ProgressBar1.value = 0
$ProgressBar1.location = New-Object System.Drawing.Point(11,165)
$Groupbox1.controls.AddRange(@($Label1,$sourcePath,$Button1))
$Form.controls.AddRange(@($Groupbox1,$Groupbox2,$Button3,$ProgressBar1))
$Groupbox2.controls.AddRange(@($Label2,$Button2,$destinationPath))
$Button1.Add_Click({ getsource })
$Button2.Add_Click({ getdest })
$Button3.Add_Click({ doSomething })
Aquest és el formulari generat per POSHGUI, en ell es genera un Form1 que conté dos Groupbox (que al mateix temps aquests contenenen cada una un TextBox, Label i Button), una ProgressBar i un Button. Sols he identificat clarament $destinationPath i $sourcePath per comoditat, recomano que identifiqueu els components per facilitar la feina a l’hora de treballar amb ells.
Veieu que inicia els controls amb contenido.controls.AddRange(@($control1….)), això indica cada control a on pertany, si modifiquéssim la posició de $Groupbox1, per exemple, el seu contingut es veuria afectat i si us fixeu, les posicions dels controls de cada Groupbox son les mateixes.
Al final declarem uns events click per als tres botons i quina funció criden al disperar-se l’event.
No posaré tot el codi, dedicaré un altre post a descriure una mica els diàlegs del sistema que podem cridar, aquí crido un OpenFileDialog pel fitxer d’origen i un SaveFileDialog pel fitxer de destí. No són ni deu línies de codi i ens faciliten molt la vida.
En acabar tenim el botó per executar l’script principal, que bolca byte a byte en una array el contingut de fitxer d’origen i realitza sobre aquest la modificació, en acabar desa el fitxer.
Com podeu veure hi ha una ProgressBar i com que podem saber la quantitat/llargada de l’array amb la que treballarem, podem calcular molt fàcilment el percentatge que portem processat de fitxer.
$ProgressBar1.value = ( $i / $size ) * 100
Hem desat la mida de l’array a $size i la $i és la variable que fem servir per recorrer l’array, senzill. El valor value de $ProgressBar1 va de 0 a 100 i un cop assignat la barra s’auto-dibuixa sola.
Podem rematar la feina amb un petit DialogBox que ens dirà que la feina esta feta i de pas ens reprodueix un so que ens permetrà saber que ha acabat.
[System.Windows.MessageBox]::Show('Done')
Al final de totes les funcions, sols ens queda una cosa, cridar el formulari:
[void]$Form.ShowDialog()
Espero que us serveixi per els vostres projectes, l’scripting és una cosa principalment “opaca” de cara a l’usuari, no sap què passa ni què esta fent, o sol ser per executar per línia de comandes, però sempre ens podrà ajudar a fer el nostre script mes amigable.
Pingback: IP Scanner en Powershell – Blog de Kamencesc