Benutzer mit den meisten Antworten
FileSystemWatcher kommt nicht mit Form zurecht

Frage
-
Hallo,
ich habe in meinem Programm eine GUI programmiert und außerdem den FileSystemWatcher integriert, der ein Verzeichnis überwachen soll. Hier das ganze mal auf ein Minimalbeispiel runtergebrochen:
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
$Form = New-Object System.Windows.Forms.Form
$F = New-Object System.IO.FileSystemWatcher
$F.Path = "F:\Test"
$F.EnableRaisingEvents = $true
Register-ObjectEvent -InputObject $F -EventName Created -Action{write-host new file created}$Form.ShowDialog()| Out-Null
Das Problem bei der ganzen Sache ist, dass die Aktion, die ausgeführt werden soll, wenn eine neue Datei im Verzeichnis entsteht, erst dann ausgeführt wird, wenn ich die Form schließe, d.h. erst dann kommt in der Konsole die Ausgabe "new file created".
Was kann ich tun, damit diese Ausgabe bereits während die GUI noch vorhanden ist gemacht wird?
Antworten
-
@Kamil die Methode Show() Funktioniert in PowerShell nicht, da PowerShell keine Nachrichtenschleife hat. Nur die Methode ShowDialog() erzeugt eine Nachrichtenschleife.
Hier müssen 2 (oder mehrere) Dinge gleichzeitig von PowerShell abgearbeitet werden.
PowerShell arbeitet immer seriell und synchron
PowerShell arbeitet immer eine Aufgabe nach der anderen ab. Dies nennt man auch serielle Abarbeitung. Der Vorteil bei dieser Arbeitsweise ist, dass die Daten im gleichen Takt erstellt und abgeholt werden können dies ist die synchrone Abarbeitung.
Während die PowerShell lang andauernde Aufträge abarbeitet, kann Sie nicht mehr auf eingaben reagieren.
Die PowerShell ist blockiert.
Ebenso geht es einer Grafischen Oberfläche (GUI). Während die GUI im Hintergrund etwas bearbeitet, kann sie nicht auf Tastatur oder Mausereignisse reagieren.
Die GUI scheint eingefroren zu sein und ist ebenfalls blockiert.
PowerShell kann parallel und asynchron arbeiten
PowerShell bietet zum Parallelen (gleichzeitigen) und asynchronen abarbeiten von mehreren Aufgaben gleichzeitig 2 verschiedene Techniken:
PowerShell Jobs
PowerShell Runspaces
PowerShell Jobs nutzen mehrere Prozesse Multiprocessing oder auch Multitasking genannt.
PowerShell Runspaces nutzen Threads die Innerhalb eines einzigen Prozesses ablaufen, Multithreading genannt.
Ich glaube mit den PowerShell Jobs kommst du nicht dahin wo du hin willst.
Du brauchst Multithreading
Der Begriff Multithreading (auch Nebenläufigkeit, Mehrsträngigkeit oder Mehrfädigkeit genannt) bezeichnet
die Aufteilung eines Programmes in mehrere gleichzeitig abzuarbeitende Bearbeitungsstränge (Threads) innerhalb eines einzelnen Prozesses oder eines Tasks (ein Anwendungsprogramm).
Prozess
Ein Prozess ist eine ausführende Instanz einer Anwendung. Wenn man z. B. PowerShell.exe ausführt, dann startet man einen Prozess, der die Windows PowerShell ausführt.
Ein Prozess bekommt von dem Betriebssystem eine Umgebung in dem der Prozess ablaufen kann. Der Prozess bekommt seinen eigenen Speicherplatz, seinen eigenen Stack (Speicher-Stapel um Variablen abzulegen) und einen Satz von Windows-Umgebungsvariablen.
Thread
Beim Start eines Prozesse wird nur ein einziger (primärer) Thread (Handlungsfaden) erzeugt der alle Befehle nacheinander abarbeitet.
Der Prozess erzeugt und Verwaltet die Umgebung, in der ein oder mehrere Threads arbeiten können.
Da der PowerShell Prozess nur einen Thread hat erzeugt dies eine streng sequentiellen (serielle) Programmausführung.
Man kann sich das Vorstellen wie eine Einbahnstraße mit Überholverbot. Alle Fahrzeuge müssen dem ersten Fahrzeug folgen und können nicht an dem ersten Fahrzeug vorbei.
Bleibt das erste Fahrzeug stehen ist die Straße (der Thread) blockiert!
Die Windows Form wird mit der Methode ShowDialog() gestartet diese Methode Zeigt die Form an und wartet auf Eingaben des Benutzers. Dies Blockiert den Thread!
Bei Bedarf können Anwendung zusätzliche Threads erstellen.
Möchte man Überholen oder mehrere Sachen gleichzeitig (Parallel) ablaufen lassen, benötigt man mehrere Straßen Spuren nebeneinander. Bei Multithreading erzeugt man neben dem primären Thread noch zusätzliche Threads (Handlungsfäden) die nebeneinander parallel Arbeiten können.
Vorteile von Threads:
Durchführen zeitaufwendiger Operationen in einem parallelen Ausführungsstrang.
Gute Skalierung auf Mehrkern-Prozessor-Systemen. Jeder Thread läuft auf einem Prozessorkern und nutzt die vorhandenen Ressourcen effizient aus.
Nicht blockierende Kommunikation über ein Netzwerk, mit einem Webserver und mit einer Datenbank.
Unterscheiden von Aufgaben nach unterschiedlicher Priorität. Ein Thread mit hoher Priorität übernimmt beispielsweise Aufgaben mit hoher Dringlichkeitsstufe, während ein Thread mit niedriger Priorität andere Aufgaben ausführt.
Aufrechterhalten der Benutzeroberflächen-Reaktivität, während Hintergrundaufgaben bearbeitet werden.
Nachteile von Threads:
Nachdem ein Threads gestartet wurde, ist er mit Arbeit beschäftig und man kann mit dem Thread nur sehr schwer kommunizieren um den Thread von außen zu steuern.
Das Steuern der Codeausführung mit vielen Threads ist sehr komplex und kann zusätzliche Fehler verursachen.
Ebenso kann es vorkommen, dass mehrere Threads im gleichen Moment eine Ressource (Variable) benötigen. Hier muss geregelt werden wann welcher Thread die Ressource haben kann.
Mehrere Threads müssen synchronisiert werden und die Fehlersuche (Debuging) gestaltet sich sehr schwierig.
Eine große Anzahl von Threads nimmt einen beträchtlichen Teil der CPU-Zeit in Anspruch. Bei zu vielen Threads kann die Ausführung der meisten nur ungenügend vorankommen. Das Betriebssystem muss sehr oft zwischen den Threads hin- und herschalten, was zu mehr Overhead führt. Wenn sich die meisten der aktuellen Threads in einem Prozess befinden, werden Threads in anderen Prozessen weniger häufig in den Ablaufplan aufgenommen.
Das Betriebssystem nimmt Arbeitsspeicher für die Kontextinformationen in Anspruch, die für Prozesse, AppDomain-Objekte und Threads erforderlich sind. Deshalb ist die Anzahl der Prozesse, AppDomain-Objekte und Threads, die erstellt werden können, durch den verfügbaren Arbeitsspeicher begrenzt.
Das Löschen von Threads erfordert Kenntnisse über mögliche Auswirkungen auf das Programm und deren Behandlung
-----------------------------------------------------------------------------------------------------------------------------------
Lange Rede Kurzer Sinn:
Das ist nicht einfach ;-)
Du musst die Grafische Benutzeroberfläche in einem Thread Starten. Und den Filesystemwatcher in einem anderen Thread.
Dann musst du es noch hinbekommen das diese beiden Treads miteinander kommunizieren.
Hier ein paar Links für dich zum Start:
Thread = Runspace !
In der PowerShell wird ein Thread von einem so genannten Runspace zur Verfügung gestellt.
Multithreading (Asynchronität) in der PowerShell:
Mann muss mit Runspaces (Sessions) und der Methode Create [PowerShell]::Create Arbeiten.
http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
Ein sehr gutes Video Tutorial gibt es von Dr. Tobias Weltner
How to speed up Windows PowerShell using multithreading
http://www.youtube.com/watch?v=hJwhyVXiOLg
gute Blog Post:
Concurrency in PowerShell: Multi-threading with Runspaces
http://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/
zum „übergeben“ von Daten kann man eine Synchronisierte Hashtable nehmen
Asynchronicity in PowerShell
http://cjoprey.blog.com/2009/08/17/asynchronicity-in-powershell/
PowerShell and WPF: Writing Data to a UI From a Different Runspace
http://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/Beispiel Code von Bruce Payette [MSFT]:
<# HowTo: Create Windows Form asynchronous without Stopping the PowerShell Script from Processing Link: http://www.vistax64.com/powershell/16998-howto-create-windows-form-without-stopping-script-processing.html Author: Bruce Payette [MSFT] #> # Zuerst wird die Windows Form erstellt ######################################################### # hier wird eine einfache Form mit einer Textbox erstellt # in der Textbox soll Text angezeigt werden # Die Form wird noch nicht gestartet! # $dForm = New-Object System.Windows.Forms.Form $dForm.Size = new-object System.Drawing.Size 640,480 $dForm.Text = "Debug Information" # TextBox erstellen die die ganze Form ausfüllt $dTextBox = New-Object System.Windows.Forms.TextBox $dTextBox.ScrollBars = "both" $dTextBox.Dock = "fill" $dTextBox.Multiline = $true $dTextBox.Parent = $dForm $dTextBox.ReadOnly = $true # im ereignis Shown der Form wird die Form Aktiv gesetzt $dForm.Add_Shown({$dform.Activate()}) # Der PowerShell Runspace (Thread) wird erstellt ######################################################### # In diesem Runspace-Thread soll die Windows Forms GUI laufen # $Runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() # öffnen des Runspaces $Runspace.Open() # Die Windows Form wird als Variable in die Umgebung des Runspace-Thread erstellt und übergeben # damit die Form auch in dem neuen Runspace-Thread vorhanden ist # Im neuen Runspace-Thread bekommt die Variable den selben Namen wie in diesem Runspace-Thread $Runspace.SessionStateProxy.SetVariable("dForm", $dForm) # Eine synchronisierte hashtable wird erstellt, # um Daten zwischen den Threads austauschen können $SynchronizedHash = [hashtable]::Synchronized(@{text=""}) # die synchronisierte hashtable wird in den Runspace-Thread erstellt und übergeben # Im neuen Runspace-Thread bekommt die Variable den selben Namen wie in diesem Runspace-Thread $Runspace.SessionStateProxy.SetVariable("SynchronizedHash", $SynchronizedHash) # Eine PowerShell Pipeline wird erstellt in der die Windows Form gestartet werden soll $RunspacePipeline = $Runspace.CreatePipeline({ [void] $dForm.ShowDialog()}) # von der Pipeline wird der Inputstream geschlossen, sonnst würde dieser die Pipeline blockieren $RunspacePipeline.Input.Close() # Die Windows Form wird Asynchron (parallel) angezeigt ######################################################### # hier wird die Pipeline Asynchron (parallel) gesartet # erst jetzt wird die Form mit ShowDialog() angezeigt $RunspacePipeline.InvokeAsync() # Hilfs-Funktion zum übergeben von beliebigen Text an die Form ############################################################## # Funktion die immer wieder aufgerufen werden kann, # um Text an die Textbox in der Windows Form zu senden Function Add-TextToWindow { param( [Parameter(ValueFromPipeline=$True)] [String]$text ) process { # Der Text der dieser Funktion übergeben wurde wird # in die synchronisierte hashtable geschrieben $SynchronizedHash.text = $text + "`n" # einen Eventhandler erstellen der später für die Invoke Methode benötigt wird # $This ist die Textbox # Dieser Eventhandler holt Text aus der synchronisierte hashtable und # ruft die Methode AppendText() von der Textbox auf [EventHandler] $EventHandler = {$this.AppendText($SynchronizedHash.text)} # Es könnte sein das die Windows Form noch nicht bereit ist # hier wird dieser Fehler abgefangen und darauf gewartet das die Form bereit ist do { $retry = @($false) trap [InvalidOperationException] { Start-Sleep -milli 100 $retry[0] = $true continue } # Steuerelemente in Windows Forms sind an einen bestimmten Thread gebunden und nicht threadsicher. # Abgesehen von der InvokeRequired-Eigenschaft können vier Methoden in einem Steuerelement threadsicher aufgerufen werden: # Invoke, BeginInvoke, EndInvoke und CreateGraphics, wenn das Steuerelement (das Handle) bereits erstellt wurde. $dTextBox.Invoke($EventHandler, ($dTextBox, [eventargs]::empty)) } while ($retry[0]) } } # PowerShell kann hier nun Arbeiten, während die Windows Form angezeigt wird ############################################################################ # # mit der Function Add-TextToWindow kann nun Text zum Fenster gesendet werden Add-TextToWindow "The date is $(Get-Date)" 1..10 | ForEach-Object { Add-TextToWindow "Some text $_" start-sleep -milli 100 } Get-ChildItem $env:windir | Select-Object -ExpandProperty Fullname | Add-TextToWindow Add-TextToWindow "The date is $(Det-Date)" Start-Sleep 2 # Windows Forms GUI wieder entfernen (aufräumen ist wichtig ;-) ) ################################################################ # # Die Windows Form Schliessen $dForm.Close() # den Runspace-Thread schliessen $Runspace.Close() # nun hat PowerShell wieder nur einen Thread!
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Mittwoch, 9. April 2014 12:44
- Als Antwort markiert Alex Pitulice Dienstag, 22. April 2014 09:49
Alle Antworten
-
@Kamil die Methode Show() Funktioniert in PowerShell nicht, da PowerShell keine Nachrichtenschleife hat. Nur die Methode ShowDialog() erzeugt eine Nachrichtenschleife.
Hier müssen 2 (oder mehrere) Dinge gleichzeitig von PowerShell abgearbeitet werden.
PowerShell arbeitet immer seriell und synchron
PowerShell arbeitet immer eine Aufgabe nach der anderen ab. Dies nennt man auch serielle Abarbeitung. Der Vorteil bei dieser Arbeitsweise ist, dass die Daten im gleichen Takt erstellt und abgeholt werden können dies ist die synchrone Abarbeitung.
Während die PowerShell lang andauernde Aufträge abarbeitet, kann Sie nicht mehr auf eingaben reagieren.
Die PowerShell ist blockiert.
Ebenso geht es einer Grafischen Oberfläche (GUI). Während die GUI im Hintergrund etwas bearbeitet, kann sie nicht auf Tastatur oder Mausereignisse reagieren.
Die GUI scheint eingefroren zu sein und ist ebenfalls blockiert.
PowerShell kann parallel und asynchron arbeiten
PowerShell bietet zum Parallelen (gleichzeitigen) und asynchronen abarbeiten von mehreren Aufgaben gleichzeitig 2 verschiedene Techniken:
PowerShell Jobs
PowerShell Runspaces
PowerShell Jobs nutzen mehrere Prozesse Multiprocessing oder auch Multitasking genannt.
PowerShell Runspaces nutzen Threads die Innerhalb eines einzigen Prozesses ablaufen, Multithreading genannt.
Ich glaube mit den PowerShell Jobs kommst du nicht dahin wo du hin willst.
Du brauchst Multithreading
Der Begriff Multithreading (auch Nebenläufigkeit, Mehrsträngigkeit oder Mehrfädigkeit genannt) bezeichnet
die Aufteilung eines Programmes in mehrere gleichzeitig abzuarbeitende Bearbeitungsstränge (Threads) innerhalb eines einzelnen Prozesses oder eines Tasks (ein Anwendungsprogramm).
Prozess
Ein Prozess ist eine ausführende Instanz einer Anwendung. Wenn man z. B. PowerShell.exe ausführt, dann startet man einen Prozess, der die Windows PowerShell ausführt.
Ein Prozess bekommt von dem Betriebssystem eine Umgebung in dem der Prozess ablaufen kann. Der Prozess bekommt seinen eigenen Speicherplatz, seinen eigenen Stack (Speicher-Stapel um Variablen abzulegen) und einen Satz von Windows-Umgebungsvariablen.
Thread
Beim Start eines Prozesse wird nur ein einziger (primärer) Thread (Handlungsfaden) erzeugt der alle Befehle nacheinander abarbeitet.
Der Prozess erzeugt und Verwaltet die Umgebung, in der ein oder mehrere Threads arbeiten können.
Da der PowerShell Prozess nur einen Thread hat erzeugt dies eine streng sequentiellen (serielle) Programmausführung.
Man kann sich das Vorstellen wie eine Einbahnstraße mit Überholverbot. Alle Fahrzeuge müssen dem ersten Fahrzeug folgen und können nicht an dem ersten Fahrzeug vorbei.
Bleibt das erste Fahrzeug stehen ist die Straße (der Thread) blockiert!
Die Windows Form wird mit der Methode ShowDialog() gestartet diese Methode Zeigt die Form an und wartet auf Eingaben des Benutzers. Dies Blockiert den Thread!
Bei Bedarf können Anwendung zusätzliche Threads erstellen.
Möchte man Überholen oder mehrere Sachen gleichzeitig (Parallel) ablaufen lassen, benötigt man mehrere Straßen Spuren nebeneinander. Bei Multithreading erzeugt man neben dem primären Thread noch zusätzliche Threads (Handlungsfäden) die nebeneinander parallel Arbeiten können.
Vorteile von Threads:
Durchführen zeitaufwendiger Operationen in einem parallelen Ausführungsstrang.
Gute Skalierung auf Mehrkern-Prozessor-Systemen. Jeder Thread läuft auf einem Prozessorkern und nutzt die vorhandenen Ressourcen effizient aus.
Nicht blockierende Kommunikation über ein Netzwerk, mit einem Webserver und mit einer Datenbank.
Unterscheiden von Aufgaben nach unterschiedlicher Priorität. Ein Thread mit hoher Priorität übernimmt beispielsweise Aufgaben mit hoher Dringlichkeitsstufe, während ein Thread mit niedriger Priorität andere Aufgaben ausführt.
Aufrechterhalten der Benutzeroberflächen-Reaktivität, während Hintergrundaufgaben bearbeitet werden.
Nachteile von Threads:
Nachdem ein Threads gestartet wurde, ist er mit Arbeit beschäftig und man kann mit dem Thread nur sehr schwer kommunizieren um den Thread von außen zu steuern.
Das Steuern der Codeausführung mit vielen Threads ist sehr komplex und kann zusätzliche Fehler verursachen.
Ebenso kann es vorkommen, dass mehrere Threads im gleichen Moment eine Ressource (Variable) benötigen. Hier muss geregelt werden wann welcher Thread die Ressource haben kann.
Mehrere Threads müssen synchronisiert werden und die Fehlersuche (Debuging) gestaltet sich sehr schwierig.
Eine große Anzahl von Threads nimmt einen beträchtlichen Teil der CPU-Zeit in Anspruch. Bei zu vielen Threads kann die Ausführung der meisten nur ungenügend vorankommen. Das Betriebssystem muss sehr oft zwischen den Threads hin- und herschalten, was zu mehr Overhead führt. Wenn sich die meisten der aktuellen Threads in einem Prozess befinden, werden Threads in anderen Prozessen weniger häufig in den Ablaufplan aufgenommen.
Das Betriebssystem nimmt Arbeitsspeicher für die Kontextinformationen in Anspruch, die für Prozesse, AppDomain-Objekte und Threads erforderlich sind. Deshalb ist die Anzahl der Prozesse, AppDomain-Objekte und Threads, die erstellt werden können, durch den verfügbaren Arbeitsspeicher begrenzt.
Das Löschen von Threads erfordert Kenntnisse über mögliche Auswirkungen auf das Programm und deren Behandlung
-----------------------------------------------------------------------------------------------------------------------------------
Lange Rede Kurzer Sinn:
Das ist nicht einfach ;-)
Du musst die Grafische Benutzeroberfläche in einem Thread Starten. Und den Filesystemwatcher in einem anderen Thread.
Dann musst du es noch hinbekommen das diese beiden Treads miteinander kommunizieren.
Hier ein paar Links für dich zum Start:
Thread = Runspace !
In der PowerShell wird ein Thread von einem so genannten Runspace zur Verfügung gestellt.
Multithreading (Asynchronität) in der PowerShell:
Mann muss mit Runspaces (Sessions) und der Methode Create [PowerShell]::Create Arbeiten.
http://msdn.microsoft.com/en-us/library/system.management.automation.powershell_members%28v=vs.85%29.aspx
Ein sehr gutes Video Tutorial gibt es von Dr. Tobias Weltner
How to speed up Windows PowerShell using multithreading
http://www.youtube.com/watch?v=hJwhyVXiOLg
gute Blog Post:
Concurrency in PowerShell: Multi-threading with Runspaces
http://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/
zum „übergeben“ von Daten kann man eine Synchronisierte Hashtable nehmen
Asynchronicity in PowerShell
http://cjoprey.blog.com/2009/08/17/asynchronicity-in-powershell/
PowerShell and WPF: Writing Data to a UI From a Different Runspace
http://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/Beispiel Code von Bruce Payette [MSFT]:
<# HowTo: Create Windows Form asynchronous without Stopping the PowerShell Script from Processing Link: http://www.vistax64.com/powershell/16998-howto-create-windows-form-without-stopping-script-processing.html Author: Bruce Payette [MSFT] #> # Zuerst wird die Windows Form erstellt ######################################################### # hier wird eine einfache Form mit einer Textbox erstellt # in der Textbox soll Text angezeigt werden # Die Form wird noch nicht gestartet! # $dForm = New-Object System.Windows.Forms.Form $dForm.Size = new-object System.Drawing.Size 640,480 $dForm.Text = "Debug Information" # TextBox erstellen die die ganze Form ausfüllt $dTextBox = New-Object System.Windows.Forms.TextBox $dTextBox.ScrollBars = "both" $dTextBox.Dock = "fill" $dTextBox.Multiline = $true $dTextBox.Parent = $dForm $dTextBox.ReadOnly = $true # im ereignis Shown der Form wird die Form Aktiv gesetzt $dForm.Add_Shown({$dform.Activate()}) # Der PowerShell Runspace (Thread) wird erstellt ######################################################### # In diesem Runspace-Thread soll die Windows Forms GUI laufen # $Runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() # öffnen des Runspaces $Runspace.Open() # Die Windows Form wird als Variable in die Umgebung des Runspace-Thread erstellt und übergeben # damit die Form auch in dem neuen Runspace-Thread vorhanden ist # Im neuen Runspace-Thread bekommt die Variable den selben Namen wie in diesem Runspace-Thread $Runspace.SessionStateProxy.SetVariable("dForm", $dForm) # Eine synchronisierte hashtable wird erstellt, # um Daten zwischen den Threads austauschen können $SynchronizedHash = [hashtable]::Synchronized(@{text=""}) # die synchronisierte hashtable wird in den Runspace-Thread erstellt und übergeben # Im neuen Runspace-Thread bekommt die Variable den selben Namen wie in diesem Runspace-Thread $Runspace.SessionStateProxy.SetVariable("SynchronizedHash", $SynchronizedHash) # Eine PowerShell Pipeline wird erstellt in der die Windows Form gestartet werden soll $RunspacePipeline = $Runspace.CreatePipeline({ [void] $dForm.ShowDialog()}) # von der Pipeline wird der Inputstream geschlossen, sonnst würde dieser die Pipeline blockieren $RunspacePipeline.Input.Close() # Die Windows Form wird Asynchron (parallel) angezeigt ######################################################### # hier wird die Pipeline Asynchron (parallel) gesartet # erst jetzt wird die Form mit ShowDialog() angezeigt $RunspacePipeline.InvokeAsync() # Hilfs-Funktion zum übergeben von beliebigen Text an die Form ############################################################## # Funktion die immer wieder aufgerufen werden kann, # um Text an die Textbox in der Windows Form zu senden Function Add-TextToWindow { param( [Parameter(ValueFromPipeline=$True)] [String]$text ) process { # Der Text der dieser Funktion übergeben wurde wird # in die synchronisierte hashtable geschrieben $SynchronizedHash.text = $text + "`n" # einen Eventhandler erstellen der später für die Invoke Methode benötigt wird # $This ist die Textbox # Dieser Eventhandler holt Text aus der synchronisierte hashtable und # ruft die Methode AppendText() von der Textbox auf [EventHandler] $EventHandler = {$this.AppendText($SynchronizedHash.text)} # Es könnte sein das die Windows Form noch nicht bereit ist # hier wird dieser Fehler abgefangen und darauf gewartet das die Form bereit ist do { $retry = @($false) trap [InvalidOperationException] { Start-Sleep -milli 100 $retry[0] = $true continue } # Steuerelemente in Windows Forms sind an einen bestimmten Thread gebunden und nicht threadsicher. # Abgesehen von der InvokeRequired-Eigenschaft können vier Methoden in einem Steuerelement threadsicher aufgerufen werden: # Invoke, BeginInvoke, EndInvoke und CreateGraphics, wenn das Steuerelement (das Handle) bereits erstellt wurde. $dTextBox.Invoke($EventHandler, ($dTextBox, [eventargs]::empty)) } while ($retry[0]) } } # PowerShell kann hier nun Arbeiten, während die Windows Form angezeigt wird ############################################################################ # # mit der Function Add-TextToWindow kann nun Text zum Fenster gesendet werden Add-TextToWindow "The date is $(Get-Date)" 1..10 | ForEach-Object { Add-TextToWindow "Some text $_" start-sleep -milli 100 } Get-ChildItem $env:windir | Select-Object -ExpandProperty Fullname | Add-TextToWindow Add-TextToWindow "The date is $(Det-Date)" Start-Sleep 2 # Windows Forms GUI wieder entfernen (aufräumen ist wichtig ;-) ) ################################################################ # # Die Windows Form Schliessen $dForm.Close() # den Runspace-Thread schliessen $Runspace.Close() # nun hat PowerShell wieder nur einen Thread!
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Mittwoch, 9. April 2014 12:44
- Als Antwort markiert Alex Pitulice Dienstag, 22. April 2014 09:49