PowerShell Windows Forms-GUI
Hier ein paar Beispiele für einfache PowerShell-GUI-Anwendungen mit Windows-Forms.
Mit PowerShell und Windows Forms können einfache Fensteranwendungen erstellt werden. Die Fensterobjekte werden dabei direkt aus PowerShell aufgerufen. Eine einfache Alternative zur hier vorgestellten PowerShell GUI mit Windows-Forms bietet WPF-XAML. Der Hauptvorteil einer PowerShell-WPF-Anwendung ist die Trennung von Layout und Quellcode: siehe: PowerShell WPF GUI - Voraussetzungen und erste GUI Anwendung
MessageBox: einfacher JA - Nein Dialog
Quellcode:
$remember=[System.Windows.Forms.MessageBox]::Show("$($selection.Application) Frage mit ja oder nein" , "Fenstertitel" , 4)
Die Messagebox gibt "Yes" oder "No" zurück, mittels if kann die Antwort weiterverarbeitet werden:
if ($remember -eq "Yes") {write-host "Yes"}else {write-host "Nein"}
Beim Drücken auf "Ja" liefert das Skript "Yes" als Antwort:
GUI-Menü
$Question = $host.ui.PromptForChoice(
"Window Title", "Question?",(
[System.Management.Automation.Host.ChoiceDescription[]](
(New-Object System.Management.Automation.Host.ChoiceDescription "&Answer1","Answer1"),
(New-Object System.Management.Automation.Host.ChoiceDescription "&Answer2","Answer2")
)
), 0
)
switch($Question){
0 {Write-Host "Answer1"}
1 {Write-Host "Answer2"}
}
Erweitert: GUI erzeugen und anzeigen: Leeres Fenster
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
[void]$window.ShowDialog()
Text in das Fenster schreiben
Quellcode:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,10)
$Label.Text = "Text im Fenster"
$Label.AutoSize = $True
$window.Controls.Add($Label)
[void]$window.ShowDialog()
Eingabefeld
Quellcode:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,10)
$Label.Text = "Text im Fenster"
$Label.AutoSize = $True
$window.Controls.Add($Label)
$windowTextBox = New-Object System.Windows.Forms.TextBox
$windowTextBox.Location = New-Object System.Drawing.Size(10,30)
$windowTextBox.Size = New-Object System.Drawing.Size(500,500)
$window.Controls.Add($windowTextBox)
[void]$window.ShowDialog()
OK Button und Eventlistener
Quellcode:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,10)
$Label.Text = "Text im Fenster"
$Label.AutoSize = $True
$window.Controls.Add($Label)
$windowTextBox = New-Object System.Windows.Forms.TextBox
$windowTextBox.Location = New-Object System.Drawing.Size(10,30)
$windowTextBox.Size = New-Object System.Drawing.Size(500,500)
$window.Controls.Add($windowTextBox)
$windowButton = New-Object System.Windows.Forms.Button
$windowButton.Location = New-Object System.Drawing.Size(10,60)
$windowButton.Size = New-Object System.Drawing.Size(50,50)
$windowButton.Text = "OK"
$windowButton.Add_Click({
write-host $windowTextBox.Text
$window.Dispose()
})
$window.Controls.Add($windowButton)
[void]$window.ShowDialog()
Erklärung:
$window.Dispose()
schließt das Fenster
Bei Eingabe eines Textes und Drücken von "OK" wird das Fenster geschlossen und der Text in der Konsole ausgegeben:
alternativ könnte der Text auch im Fenster ausgeben werden, zum Beispiel in unserem ersten Beispieltext:
mit $Label.Text = $windowTextBox.Test
beim Drücken auf OK:
RadioButtons
Quellcode:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
$radioButton1 = New-Object System.Windows.Forms.RadioButton
$radioButton2 = New-Object System.Windows.Forms.RadioButton
$radioButton3 = New-Object System.Windows.Forms.RadioButton
$groupBox = New-Object System.Windows.Forms.GroupBox
$groupBox.Controls.AddRange(
@(
$radioButton1,
$radioButton2,
$radioButton3
))
$groupBox.Location = New-Object System.Drawing.Point(10, 10)
$groupBox.Name = 'groupBox'
$groupBox.Size = New-Object System.Drawing.Size(120, 144)
$groupBox.Text = 'Option'
# radioButton1
$radioButton1.Location = New-Object System.Drawing.Point(8, 32)
$radioButton1.Name = 'radioButton1'
$radioButton1.Text = 'Option1'
# radioButton2
$radioButton2.Location = New-Object System.Drawing.Point(8, 64)
$radioButton2.Name = 'radioButton2'
$radioButton2.Text = 'Option2'
# radioButton3
$radioButton3.Location = New-Object System.Drawing.Point(8, 96)
$radioButton3.Name = 'radioButton3'
$radioButton3.Text = 'Option3'
$window.Controls.Add($groupBox)
$windowButton = New-Object System.Windows.Forms.Button
$windowButton.Location = New-Object System.Drawing.Point(10,170)
$windowButton.Text = "OK"
$windowButton.Add_Click({
foreach ($o in @($radioButton1, $radioButton2, $radioButton3)){
if ($o.Checked){
$option = $o.Text}
}
write-host $option
$window.Dispose()
})
$window.Controls.Add($windowButton)
[void]$window.ShowDialog()
GUI Timer: Background Loop und Scope
Update der GUI mittels Timer-Event.
Quellcode:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$window = New-Object System.Windows.Forms.Form
$window.Width = 1000
$window.Height = 800
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,10)
$Label.Text = "Text im Fenster"
$Label.AutoSize = $True
$window.Controls.Add($Label)
$i=0
$timer_Tick={
$script:i++
$Label.Text= "$i new text"
}
$timer = New-Object 'System.Windows.Forms.Timer'
$timer.Enabled = $True
$timer.Interval = 1000
$timer.add_Tick($timer_Tick)
[void]$window.ShowDialog()
Scope: Gültigkeitsbereich
Innerhalb von Funktionen, hier $timer_Tick
, ist ein anderer Gültigkeitsbereich für Variablen (Scope). Um mit $i++
die Variable $i
dauerhauft um eins zu erhöhen, muss $i
in einem Scope verwendet werden der auch außerhalb der Funktion gültig ist. Beispiele dafür sind $global:i
oder $script:i
Ohne "global" oder "script" würden Änderungen an $i
in einer Funktion nicht gespeichert werden, daher würde die Änderung an $i
innerhalb von $timer_Tick
immer wieder verloren gehen: $i
würde dann zu Beginn der Funktion $timer_Tick
0 sein und immer wieder um 1 erhöht also bei jedem Durchlauf der Funktion von 0 auf 1 erhöht werden. Durch Einsatz vom Gültigkeitsbereich:script wird die Variable auch nach dem Ausführen der Funktion gespeichert. $i wird somit mit jedem Funktionsaufruf um eins erhöht 1,2,3,4,5 ....
Der Gültigkeitsbereich:script ist nur innerhalb des Skripts gültig, der Gültigkeitsbereich: global ist auch außerhalb des Skripts verfügbar, dies würde in diesem Fall über das Ziel hinaus schießen.
{{percentage}} % positiv
DANKE für deine Bewertung!
Fragen / Kommentare
(sortiert nach Bewertung / Datum) [alle Kommentare(neueste zuerst)]
sehr gut erklärt! Kann man auch das Ergebnis einer Abfrage, zB. wann der PC gestartet wurde: Get-WmiObject -class Win32_OperatingSystem | Select-Object __SERVER,@{label=’LastRestart‘;expression={$_.ConvertToDateTime($_.LastBootUpTime)}} in der Box anzeigen? sodass im Titel dann steht "letzter Start" und als Text das Datum mit Uhrzeit, zB: "31.05.2024 11:27" Das wäre toll.