vendredi 14 décembre 2012

Utilisation des Runspace (2/2).

Voici le troisième exemple autour du Runspace. Cette fois nous allons nous voir comment envoyer des données vers le Runspace en passant par le pipeline. Dans le champ texte, saisissez votre prénom, puis cliquez sur le bouton pour voir le résultat s'afficher en dessous.

 
#Ouvre une fenêtre.
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$form = New-Object Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(215,115)
$form.text = "Exemple 3"

#Création du Runspace.
$runspace1 = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$runspace1.Open()

#Création d'un timer pour tester la fin de l'execution du script dans le runspace.
$running = [System.Management.Automation.Runspaces.PipelineState]::Running
$timer1 = new-object System.Windows.forms.timer
$timer1.Interval = (1000) #milliseconds.
$timer1.Add_Tick({
                   if ($pipeline1.PipelineStateInfo.State -ne $running)
                     {
                       $timer1.Stop()  #Arrêt du timer.


                       #Récupère la variable retournée par le runspace.
                       foreach ($result in $global:pipeline1.Output.ReadToEnd())
                        { 

                          #Valeur retournée par le Runspace.
                          $label1.Text = $result 


                          #Actualise le contrôle.
                          $label1.refresh()

                        }
                     }
                })

#Création label 1 (Label).
$label1 = New-Object Windows.Forms.Label
$label1.Location = New-Object Drawing.Point 120,50
$label1.Size = New-Object Drawing.Point 100,16
$label1.Text = "--------"

#Création texte 1 (TextBox).
$texte1 = New-Object Windows.Forms.TextBox
$texte1.Location = New-Object Drawing.Point 20,20
$texte1.Size = New-Object Drawing.Point 80,16
$texte1.Text = "Jumbor12"

#Création bouton 1 (Button).
$bouton1 = New-Object Windows.Forms.Button
$bouton1.Location = New-Object Drawing.Point 120,20
$bouton1.Size = New-Object Drawing.Point 65,21
$bouton1.text = "Tâche 1"
$bouton1.add_click({
                     $label1.Text = "En cours..."
                     $label1.refresh()

                     #Création du canal de communication avec le Runspace.
                     $pipeline1 = $runspace1.CreatePipeline()

                     #Ajout des commande à executer dans le runspace.
                     $pipeline1.Commands.AddScript({
                                                      #Lecture des données.
                                                      foreach ($arg in $args)
                                                       {
                                                         #Transforme en MAJ.
                                                         $pn1 = $arg.ToUpper()

                                                         #Retourne la valeur.
                                                         $pn1
                                                       }
                                                   })
                     #Envoie les données à traiter.
                     $global:pipeline1.Commands[0].Parameters.Add($texte1.Text)


                     #Execution du script dans le Runspace.
                     $pipeline1.InvokeAsync()

                     #Lancement du timer pour verifier la fin du traitement.
                     $timer1.Start()            
                  })

#Attache le contrôle à la fenêtre.
$form.controls.add($label1)
$form.controls.add($texte1)
$form.controls.add($bouton1)

#Affiche le tout.
$form.ShowDialog()

#Libèration.
$timer1.Stop()
$runspace1.Close()

#Fin.

Dans cet exemple, je n'envoie qu'une seule donnée dans mon pipeline. Mais j'aurais également pu mettre en place une boucle autour de la ligne $global:pipeline1.Commands[0].Parameters.Add() pour envoyer plusieurs valeurs dans le pipeline. Celles-ci auraient alors été traité une par une dans la boucle foreach ($arg in $args) {}.