Powershell addShown unterbrechen wenn Abbrechen angeklickt wird
Hallo Forum.
Ich möchte während der $form.add_Shown läuft den Abbrechen-Button anklicken und hiermit das Fenster beenden. Wie kann man das umsetzen? Ist die Aktion (Hochzählen in der TextBox) abgeschlossen funktioniert der Button ja wie gewohnt.
Ich möchte während der $form.add_Shown läuft den Abbrechen-Button anklicken und hiermit das Fenster beenden. Wie kann man das umsetzen? Ist die Aktion (Hochzählen in der TextBox) abgeschlossen funktioniert der Button ja wie gewohnt.
function Get-Action
{
$ResultText = [ordered]@{}
$LabelLocationX = 10
$LabelSizeX = 200
$LabelSizeY = 30
$TextBoxLocationX = $LabelSizeX + 10
$TextBoxSizeX = 460
$DialogBoxSizeX = $TextBoxLocationX + $TextBoxSizeX + 25
$DialogBoxSizeY = 250
# ================================================================================================================================================
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size($DialogBoxSizeX,$DialogBoxSizeY)
$form.MinimumSize = New-Object System.Drawing.Size($DialogBoxSizeX,$DialogBoxSizeY)
$form.MaximumSize = New-Object System.Drawing.Size($DialogBoxSizeX,$DialogBoxSizeY)
$form.ControlBox = $false
$form.StartPosition = 'CenterScreen'
# CancelButton
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(10,200)
$CancelButton.Size = New-Object System.Drawing.Size(70,23)
$CancelButton.Text = 'Abbrechen'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.Controls.Add($CancelButton)
$TextBox = New-Object System.Windows.Forms.TextBox
$TextBox.Location = "10,10"
$TextBox.Size = "100,100"
$TextBox.ReadOnly = $true
$TextBox.Multiline = $true
$TextBox.ScrollBars = "Vertical"
$Form.Controls.Add($TextBox)
# === Action ===
$form.add_Shown({
$Counter = 0
0..10 | foreach {
$Counter += 1
$TextBox.Text = $Counter
sleep -Milliseconds 500
}
})
$form.Topmost = $true
$form.ShowDialog()
}
# ==============================================================================================================================================================================================================================
$Action = Get-Action
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 41940313715
Url: https://administrator.de/contentid/41940313715
Ausgedruckt am: 21.11.2024 um 20:11 Uhr
6 Kommentare
Neuester Kommentar
Morsche.
Genau das hatten wir ja eigentlich schon mit dir hier abgehandelt ... im nachstehenden Thread steht wie du dir den UI Thread nicht durch eine Routine blockierst.
Powershell Kopiervorgang und StatusBar mit hochlaufender Prozentzahl
Da brauchst du dann zum Abbrechen des Script-Tasks auf deinem Button nur
ausführen.
Beispielcode:
sid
Genau das hatten wir ja eigentlich schon mit dir hier abgehandelt ... im nachstehenden Thread steht wie du dir den UI Thread nicht durch eine Routine blockierst.
Powershell Kopiervorgang und StatusBar mit hochlaufender Prozentzahl
Da brauchst du dann zum Abbrechen des Script-Tasks auf deinem Button nur
$ps.Stop()
$form.Close()
Beispielcode:
Add-Type -A System.Windows.Forms
# synchronized Hashtable für den Austausch von Daten zwischen den Threads erstellen
$ht = [hashtable]::Synchronized(@{})
# Powershell thread erstellen
$ps = [powershell]::Create()
# die Hashtable als Variable "ht" dem Powershell-Runspace hinzufügen
$ps.Runspace.SessionStateProxy.SetVariable("ht",$ht)
#form erzeugen
$form = New-Object System.Windows.Forms.Form -P @{
ClientSize = '200,80'
Text = "Copystatus"
add_Shown = {
# dem separaten Powershell Thread ein Skript hinzufügen
$ps.AddScript({
# hier statt der Schleife die Aktionen einfügen und Updates an die Statusbar schicken:
1..10 | %{
$ht.statusbar.Text = "Datei $_"
sleep -Milliseconds 500
}
$ht.statusbar.Text = "Fertig"
})
$ps.BeginInvoke()
}
}
# button erzeugen
$btn = New-Object System.Windows.Forms.Button -P @{
Text = "Abbrechen"
Location = '10,20'
Size = '180,30'
Anchor = 'Bottom,Left,Right'
# aktion wenn auf den Button geklickt wird
add_Click = {
# Abbruch, Task beenden und Fenster schließen
$ps.Stop()
$form.Close()
}
}
$statusbar = [System.Windows.Forms.StatusBar]@{
Dock = "Bottom"
}
$ht.statusbar = $statusbar
$form.Controls.AddRange(@($statusbar,$btn))
[void]$form.ShowDialog()
$ps.Dispose()
sid
Nur um sicher zu gehen @HighSpeed1 Vielleicht verstehst du nicht was man eigentlich bezweckt, wenn ein Teil des Codes, bzw die GUI in einen eigene Runspace gepackt wird:
Prinzipiell kennt ein jedes Programm nur einen linearen Ablauf. Bedeutet, dass eine Aufgabe nach der anderen abgearbeitet wird.
Startest du also eine Aufgabe nachdem die GUI geladen wurde, wird diese solange "stillgelegt" bis die Aufgabe abgearbeitet ist. Oder du startest die Aufgabe zuerst und die GUI lädt erst nachdem die Aufgabe erledigt ist.
Das will man normalerweise nicht. Deshalb muss zb die GUI in einem eigenen Thread laufen. Das bewerkstelligt man mit einem Runspace. Ab da laufen GUI und Aufgabe in 2 parallel laufenden Threads und die GUI freezed nicht mehr.
Grüße!
Prinzipiell kennt ein jedes Programm nur einen linearen Ablauf. Bedeutet, dass eine Aufgabe nach der anderen abgearbeitet wird.
Startest du also eine Aufgabe nachdem die GUI geladen wurde, wird diese solange "stillgelegt" bis die Aufgabe abgearbeitet ist. Oder du startest die Aufgabe zuerst und die GUI lädt erst nachdem die Aufgabe erledigt ist.
Das will man normalerweise nicht. Deshalb muss zb die GUI in einem eigenen Thread laufen. Das bewerkstelligt man mit einem Runspace. Ab da laufen GUI und Aufgabe in 2 parallel laufenden Threads und die GUI freezed nicht mehr.
Grüße!
$ht ist eine Synchronized Hashtable die für den Datentransfer zwischen den beiden Threads fungiert.
Durch das
Und dadurch das es eine synced Hashtable ist, besitzt sie dann auch alle Eigenschaften die ihr im Hauptthread zugewiesen wurden.
Separate Threads wissen nämlich im Normalfall rein gar nichts von dem anderen Thread, auch nichts von dessen Variablen, deswegen dient hier die Synced-Hashtable quasi als Datentunnel zwischen beiden Threads.
Jetzt klarer?
$ht.statusbar = $statusbar
Dies dient dazu in der synced Hashtable die Statusbar für den anderen Threads zugreifbar zu machen. Man weist also dem Key "statusbar" der Hashtable das Objekt der Statusbar zu um später aus dem anderen Thread auf die Statusbar zugreifen zu können. Man könnte hier auch gleich die ganze Form als Objekt übergeben, das geht auch, dann muss man über die "Controls" Collection der Form auf die Statusbar zugreifen.Durch das
$ps.Runspace.SessionStateProxy.SetVariable("ht",$ht)
wird diese Hashtable dann als Variable mit dem selben Namen $ht in dem anderen Thread verfügbar gemacht.Und dadurch das es eine synced Hashtable ist, besitzt sie dann auch alle Eigenschaften die ihr im Hauptthread zugewiesen wurden.
Separate Threads wissen nämlich im Normalfall rein gar nichts von dem anderen Thread, auch nichts von dessen Variablen, deswegen dient hier die Synced-Hashtable quasi als Datentunnel zwischen beiden Threads.
Jetzt klarer?
Das ist die Hauptsache 👍