
Sommaire
I. Présentation
Après de longues heures de labeur, vous avez achevé votre super script Powershell, mais il vous reste encore à le diffuser auprès de vos collaborateurs que l’austérité de la console va certainement rebuter. Que cela ne tienne, ajoutez-lui une petite touche graphique et cela lui donnera instantanément un aspect plus appréciable 🙂
En matière d’interface graphique sous Powershell, vous avez le choix entre le traditionnel “Windows Forms” ou le “Windows Presentation Framework (alias WPF). Je vous propose d’aborder le premier choix, probablement moins “smart” mais à mon avis plus facile à mettre en œuvre (en terme d’outillage).
II. Explications
En langage Powershell, créer une interface graphique n’est pas chose facile et les techniciens comme moi, autrement dit les “non développeurs”, qui ne disposent que de très peu d’outils pour arriver à leurs fins.
Pour faire court, parmi les outils gratuits permettant de dessiner l’interface et générer le code correspondant, je n’ai retenu qu’un seul outil minimaliste mais efficace “PrimalForms CE”. Malheureusement, ce produit, proposé par Sapien n’est plus disponible depuis plusieurs années (probablement qu’il faisait de l’ombre à certains produits commerciaux 😀 ). Quoi qu’il en soit, il est toujours gratuit et fonctionnel, et au cas où vous auriez des difficultés à le trouver, je le mets à disposition ici ou là
III. Créer des applications
Après avoir installé ce petit outil, il vous suffit de lancer le raccourci “PrimalForms Community Edition“.
A. Créer le formulaire
Cliquez sur “New” pour créer votre nouvelle fenêtre d’application “Windows Forms”
A gauche, tous les “éléments de contrôle” qu’il suffit de sélectionner et déplacer vers le formulaire
A droite, toutes les “propriétés” de l’élément sélectionné. Les valeurs en gras, correspondent à des réglages modifiés par rapport à celles par défaut.
Rien de très compliqué à l’usage, mais la richesse des informations proposées est quelque peu déroutante au début.
A droite, vous disposez également des options évènementielles (handles) symbolisé par un éclair. Autrement dit, cette option permet de déclarer un événement sur le contrôle sélectionné, tel qu’un clic, une perte de focus, un changement d’état ou un autre événement.
Si vous manquez d’inspiration pour le nommage de l’élément, double-cliquez simplement dans le champ de l’événement.
B. Sauvegardez votre projet
Enregistrez votre projet via le bouton “Save” ou “Save As“. Celui-ci portera l’extension “.pff” mais correspond à un format xml qui peut être consulté avec un simple éditeur de texte, tel que Notepad ++.
Même si cela semble fastidieux au début, prenez l’habitude de nommer significativement les contrôles. Par exemple “btn_Quit”, “txt_Saisie” plutôt que “Button1, Textbox1…”
C. Générez le code Powershell
Ensuite, vous n’avez plus qu’à exporter ce formulaire graphique vers un fichier “.ps1” en cliquant sur le bouton “Export Powershell”
A noter qu’il est également possible d’exporter ce code Powershell vers le presse papier.
D. Finaliser le code Powershell
C’est l’étape la plus délicate puisqu’elle consiste à renseigner le “véritable code” de votre application.
Et la gestion des éléments graphiques augmente très rapidement le nombre de lignes. Je vous conseille d’utiliser un éditeur tel que ISE v3 ou ultérieur afin de réduire [-] ou développer [+] les différentes régions de code.
Le principal défaut est qu’il n’est pas possible de basculer entre la conception graphique et le code modifié. En cas de modification d’un élément graphique il faut jongler avec le presse papier pour modifier le code Powershell
IV. Exemple
Voici un petit exemple d’interface générée avec cet outil. Il s’agit d’un petit clavier de saisie de code PIN avec positionnement aléatoire des touches numériques (Histoire d’éviter le repérage des traces de doigts sur les écrans tactiles 😉 )
Le code (un peu long n’est-ce pas ?) – mais quand on aime on ne compte pas 😀
#Generated Form Function function GenerateForm { ######################################################################## # Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.9.0 # Generated On: 24/11/2016 18:46 # Generated By: Christophe ######################################################################## #region Import the Assemblies [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null #endregion #region Generated Form Objects $PINCode = New-Object System.Windows.Forms.Form $textBoxPIN = New-Object System.Windows.Forms.TextBox $buttonRDM = New-Object System.Windows.Forms.Button $buttonOK = New-Object System.Windows.Forms.Button $buttonBK = New-Object System.Windows.Forms.Button $button0 = New-Object System.Windows.Forms.Button $button9 = New-Object System.Windows.Forms.Button $button8 = New-Object System.Windows.Forms.Button $button7 = New-Object System.Windows.Forms.Button $button6 = New-Object System.Windows.Forms.Button $button5 = New-Object System.Windows.Forms.Button $button4 = New-Object System.Windows.Forms.Button $button3 = New-Object System.Windows.Forms.Button $button2 = New-Object System.Windows.Forms.Button $button1 = New-Object System.Windows.Forms.Button $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #endregion Generated Form Objects #---------------------------------------------- #Generated Event Script Blocks #---------------------------------------------- #Provide Custom Code for events specified in PrimalForms. $buttonRDM_OnClick= { Randomize-Buttons } $button0_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button0.Text } $button1_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button1.Text } $button2_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button2.Text } $button3_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button3.Text } $button4_Click= { $textBoxPIN.Text = $textBoxPIN.Text + $button4.Text } $button5_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button5.Text } $button6_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button6.Text } $button7_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button7.Text } $button8_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button8.Text } $button9_OnClick= { $textBoxPIN.Text = $textBoxPIN.Text + $button9.Text } $buttonBK_OnClick= { $code = $textBoxPIN.Text if ($code.length -ne 0) { $textBoxPIN.Text = $code.Substring(0,$code.length -1) } } $buttonOK_OnClick= { ####### !! CODE PIN SAISI Write-Host $textBoxPIN.Text } $OnLoadForm_StateCorrection= {#Correct the initial state of the form to prevent the .Net maximized form issue $PINCode.WindowState = $InitialFormWindowState Randomize-Buttons } #---------------------------------------------- #region Generated Form Code $PINCode.AutoScaleMode = 0 $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 192 $System_Drawing_Size.Width = 138 $PINCode.ClientSize = $System_Drawing_Size $PINCode.FormBorderStyle = 'Fixed3D' $PINCode.MaximizeBox = $false $PINCode.DataBindings.DefaultDataSourceUpdateMode = 0 $PINCode.Name = "PINCode" $PINCode.Text = "Code ?" $PINCode.TransparencyKey = [System.Drawing.Color]::FromArgb(255,25,25,112) $textBoxPIN.DataBindings.DefaultDataSourceUpdateMode = 0 $textBoxPIN.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",16,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 56 $System_Drawing_Point.Y = 10 $textBoxPIN.Location = $System_Drawing_Point $textBoxPIN.Name = "textBoxPIN" $textBoxPIN.PasswordChar = '*' $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 32 $System_Drawing_Size.Width = 75 $textBoxPIN.Size = $System_Drawing_Size $textBoxPIN.TabIndex = 14 $textBoxPIN.TextAlign = 2 $textBoxPIN.UseSystemPasswordChar = $True $PINCode.Controls.Add($textBoxPIN) $buttonRDM.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,225) $buttonRDM.DataBindings.DefaultDataSourceUpdateMode = 0 $buttonRDM.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",6,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 10 $buttonRDM.Location = $System_Drawing_Point $buttonRDM.Name = "buttonRDM" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 38 $buttonRDM.Size = $System_Drawing_Size $buttonRDM.TabIndex = 13 $buttonRDM.Text = "Rnd" $buttonRDM.UseVisualStyleBackColor = $False $buttonRDM.add_Click($buttonRDM_OnClick) $PINCode.Controls.Add($buttonRDM) $buttonOK.BackColor = [System.Drawing.Color]::FromArgb(255,166,202,240) $buttonOK.DataBindings.DefaultDataSourceUpdateMode = 0 $buttonOK.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 155 $buttonOK.Location = $System_Drawing_Point $buttonOK.Name = "buttonOK" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 36 $buttonOK.Size = $System_Drawing_Size $buttonOK.TabIndex = 12 $buttonOK.Text = "OK" $buttonOK.UseVisualStyleBackColor = $False $buttonOK.add_Click($buttonOK_OnClick) $PINCode.Controls.Add($buttonOK) $buttonBK.BackColor = [System.Drawing.Color]::FromArgb(255,128,128,128) $buttonBK.DataBindings.DefaultDataSourceUpdateMode = 0 $buttonBK.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 94 $System_Drawing_Point.Y = 155 $buttonBK.Location = $System_Drawing_Point $buttonBK.Name = "buttonBK" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 37 $buttonBK.Size = $System_Drawing_Size $buttonBK.TabIndex = 11 $buttonBK.Text = "<X" $buttonBK.UseVisualStyleBackColor = $False $buttonBK.add_Click($buttonBK_OnClick) $PINCode.Controls.Add($buttonBK) $button0.DataBindings.DefaultDataSourceUpdateMode = 0 $button0.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 50 $System_Drawing_Point.Y = 155 $button0.Location = $System_Drawing_Point $button0.Name = "button0" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 38 $button0.Size = $System_Drawing_Size $button0.TabIndex = 10 #$button0.Text = "0" $button0.UseVisualStyleBackColor = $True $button0.add_Click($button0_OnClick) $PINCode.Controls.Add($button0) $button9.DataBindings.DefaultDataSourceUpdateMode = 0 $button9.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 94 $System_Drawing_Point.Y = 121 $button9.Location = $System_Drawing_Point $button9.Name = "button9" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 37 $button9.Size = $System_Drawing_Size $button9.TabIndex = 9 #$button9.Text = "9" $button9.UseVisualStyleBackColor = $True $button9.add_Click($button9_OnClick) $PINCode.Controls.Add($button9) $button8.DataBindings.DefaultDataSourceUpdateMode = 0 $button8.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 50 $System_Drawing_Point.Y = 120 $button8.Location = $System_Drawing_Point $button8.Name = "button8" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 38 $button8.Size = $System_Drawing_Size $button8.TabIndex = 8 #$button8.Text = "8" $button8.UseVisualStyleBackColor = $True $button8.add_Click($button8_OnClick) $PINCode.Controls.Add($button8) $button7.DataBindings.DefaultDataSourceUpdateMode = 0 $button7.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 120 $button7.Location = $System_Drawing_Point $button7.Name = "button7" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 29 $System_Drawing_Size.Width = 37 $button7.Size = $System_Drawing_Size $button7.TabIndex = 7 #$button7.Text = "7" $button7.UseVisualStyleBackColor = $True $button7.add_Click($button7_OnClick) $PINCode.Controls.Add($button7) $button6.DataBindings.DefaultDataSourceUpdateMode = 0 $button6.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 94 $System_Drawing_Point.Y = 86 $button6.Location = $System_Drawing_Point $button6.Name = "button6" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 37 $button6.Size = $System_Drawing_Size $button6.TabIndex = 6 #$button6.Text = "6" $button6.UseVisualStyleBackColor = $True $button6.add_Click($button6_OnClick) $PINCode.Controls.Add($button6) $button5.DataBindings.DefaultDataSourceUpdateMode = 0 $button5.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 50 $System_Drawing_Point.Y = 86 $button5.Location = $System_Drawing_Point $button5.Name = "button5" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 38 $button5.Size = $System_Drawing_Size $button5.TabIndex = 5 #$button5.Text = "5" $button5.UseVisualStyleBackColor = $True $button5.add_Click($button5_OnClick) $PINCode.Controls.Add($button5) $button4.DataBindings.DefaultDataSourceUpdateMode = 0 $button4.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 86 $button4.Location = $System_Drawing_Point $button4.Name = "button4" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 38 $button4.Size = $System_Drawing_Size $button4.TabIndex = 4 #$button4.Text = "4" $button4.UseVisualStyleBackColor = $True $button4.add_Click($button4_Click) $PINCode.Controls.Add($button4) $button3.DataBindings.DefaultDataSourceUpdateMode = 0 $button3.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 94 $System_Drawing_Point.Y = 52 $button3.Location = $System_Drawing_Point $button3.Name = "button3" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 37 $button3.Size = $System_Drawing_Size $button3.TabIndex = 2 #$button3.Text = "3" $button3.UseVisualStyleBackColor = $True $button3.add_Click($button3_OnClick) $PINCode.Controls.Add($button3) $button2.DataBindings.DefaultDataSourceUpdateMode = 0 $button2.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 52 $System_Drawing_Point.Y = 52 $button2.Location = $System_Drawing_Point $button2.Name = "button2" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 36 $button2.Size = $System_Drawing_Size $button2.TabIndex = 1 #$button2.Text = "2" $button2.UseVisualStyleBackColor = $True $button2.add_Click($button2_OnClick) $PINCode.Controls.Add($button2) $button1.DataBindings.DefaultDataSourceUpdateMode = 0 $button1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,1,3,0) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 8 $System_Drawing_Point.Y = 52 $button1.Location = $System_Drawing_Point $button1.Name = "button1" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 28 $System_Drawing_Size.Width = 38 $button1.Size = $System_Drawing_Size $button1.TabIndex = 0 #$button1.Text = "1" $button1.UseVisualStyleBackColor = $True $button1.add_Click($button1_OnClick) $PINCode.Controls.Add($button1) #endregion Generated Form Code #Save the initial state of the form $InitialFormWindowState = $PINCode.WindowState #Init the OnLoad event to correct the initial state of the form $PINCode.add_Load($OnLoadForm_StateCorrection) #Show the Form $PINCode.ShowDialog()| Out-Null } #End Function function Randomize-Buttons { #Randomize button values $buttonValue = 0..9 | Get-Random -Count 10 $i = 0 foreach ($Item in $buttonValue) { # Write-Output "Bouton[$i] = $($buttonValue[$i])" if ("button"+$i -eq $button0.Name) { $button0.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button1.Name) { $button1.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button2.Name) { $button2.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button3.Name) { $button3.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button4.Name) { $button4.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button5.Name) { $button5.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button6.Name) { $button6.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button7.Name) { $button7.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button8.Name) { $button8.Text = $($buttonValue[$i]) } if ("button"+$i -eq $button9.Name) { $button9.Text = $($buttonValue[$i]) } $i++ } } #Call the Function GenerateForm
Bons développements à tous.
Christophe
Pingback: Powershell - Logiciel pour créer de petites applications graphiques (GUI) — Mon-pense bête tech