Building a PowerShell GUI (Part 5)

If you would like to read the other parts in this article series please go to:

In my previous article, I completely rewrote the Hello World script, using a completely different technique. In this article, I want to step you through the inner workings of the script. From there, I will show you how to adapt this technique to do something a bit more useful. For the sake of reference, here is the code from the previous article:

#Load Assemblies

[System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”) | Out-Null

[System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”) | Out-Null

$net = New-Object -ComObject Wscript.Network

 

#Define Butten Click Function

Function DisplayHelloWorldText{

Add-Type -AssemblyName System.Windows.Forms

#Create Hello World text

$Label = New-Object System.Windows.Forms.Label

$Label.Text = “Hello World”

$Label.AutoSize = $True

$Label.Location = new-object System.Drawing.Size(88,73)

$Form.Controls.Add($Label)

}

 

#Draw form

$Form = New-Object System.Windows.Forms.Form

$Form.width = 525

$Form.height = 350

$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D

$Form.Text = “Hello World”

$Form.maximumsize = New-Object System.Drawing.Size(525,350)

$Form.startposition = “centerscreen”

$Form.KeyPreview = $True

$Form.Add_KeyDown({if ($_.KeyCode -eq “Enter”) {}})

$Form.Add_KeyDown({if ($_.KeyCode -eq “Escape”)

{$Form.Close()}})

 

#Create button

$Button1 = new-object System.Windows.Forms.Button

$Button1.Location = new-object System.Drawing.Size(249,132)

$Button1.Size = new-object System.Drawing.Size(80,20)

$Button1.Text = “Button”

$Button1.Add_Click({DisplayHelloWorldText})

 

#Create the Form

$Form.Controls.Add($Button1)

$Form.Add_Shown({$Form.Activate()})

$Form.ShowDialog()

As you can see in the code sample, I have broken the code down into sections. The first section of the script loads the assemblies that we will be using. An assembly is really nothing more than just a pre-existing collection of code. In this case, Microsoft supplies the code, and that’s good news. It means that we don’t have to re-invent the wheel. If I want to create a window for example, I can just leverage an assembly rather than building code from scratch that will draw a window. In this particular case, there are two assemblies that I am loading – System.Windows.Forms and System.Drawing.

Even though we don’t have to write code that creates dialog boxes and other common interface elements from scratch, some coding is required to create these elements. After all, dialog boxes don’t just appear by magic. If we want to display a dialog box, then we have to tell Windows where to put the dialog box, and how big it should be.

The section of the script that is responsible for producing the dialog box is the Draw Form section, which you can see below:

#Draw form

$Form = New-Object System.Windows.Forms.Form

$Form.width = 525

$Form.height = 350

$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D

$Form.Text = “Hello World”

$Form.maximumsize = New-Object System.Drawing.Size(525,350)

$Form.startposition = “centerscreen”

$Form.KeyPreview = $True

$Form.Add_KeyDown({if ($_.KeyCode -eq “Enter”) {}})

$Form.Add_KeyDown({if ($_.KeyCode -eq “Escape”)

{$Form.Close()}})

If you look at the very first line of code above, you can see that I am defining a variable called $Form. This variable is being used to create a new Form object. A form is essentially the same thing as a dialog box. The remaining lines of code in this section are defining the form’s attributes. For example, we are defining the form’s width, height, border style, and even the name of the window (through $Form.Text). As you look through the block of code above, you will also notice that we are telling windows that we want to display the form in the center of the screen.

Most of the code shown in the block above is self explanatory, but the last two lines probably disserve a bit of explaining. These two lines of code define keyboard input action. In this case, we are telling PowerShell that pressing Enter is the same as clicking on the form’s button. We are also telling PowerShell to close the form if someone presses the Escape key.

The most important thing to understand about the block of code shown above is that it does not actually draw the form (or dialog box). Instead, it simply sets up the parameters that will be used when the form is drawn later on.

The Button

Just as we created a block of code to define the dialog box, there is also a block of code that defines the button. Here is what this block of code looks like:

#Create button

$Button1 = new-object System.Windows.Forms.Button

$Button1.Location = new-object System.Drawing.Size(249,132)

$Button1.Size = new-object System.Drawing.Size(80,20)

$Button1.Text = “Button”

$Button1.Add_Click({DisplayHelloWorldText})

The first line in this block of code defines a new form object of type Button. The next line indicates that the button should be placed at X=249, Y=132. The third line of code indicates that the button’s size will be 80 pixels wide, by 20 pixels high (you can make a button of any size that you want). The fourth line defines the text that will be displayed on the button. In this case, the button will simply say “Button”.

The last line of code is arguably the most important, because it tells Windows what to do when someone clicks the button. In this case, when the button is clicked, the script will call a PowerShell function called DisplayHelloWorldText.

It is worth noting that like the block of code that defines the dialog box, the button code that I have just discussed does not actually display the button. Instead, it merely defines attributes that will be used when the button is displayed.

Displaying the Form

The next block of code that I want to talk about is the code that actually displays the form. Here is the code:

#Create the Form

$Form.Controls.Add($Button1)

$Form.Add_Shown({$Form.Activate()})

$Form.ShowDialog()

Although seemingly cryptic, this block of code is quite simple. As you may recall, we have already defined a form object. This code adds our button ($Button1) to the existing form object, and then activates the form in the next line. The last line of code is what causes the dialog box and button to be displayed on the screen.

Functional Elements

The last thing that I want to talk about is the DisplayHelloWorldText function. Remember, that the script calls this function in response to a button click. Here is the function code:

#Define Butten Click Function

Function DisplayHelloWorldText{

Add-Type -AssemblyName System.Windows.Forms

#Create Hello World text

$Label = New-Object System.Windows.Forms.Label

$Label.Text = “Hello World”

$Label.AutoSize = $True

$Label.Location = new-object System.Drawing.Size(88,73)

$Form.Controls.Add($Label)

}

The thing that you must understand about this block of code is that because we are creating a graphical output, we can’t display text on the screen using the Write-Host cmdlet like we could in a text based environment. Our GUI is a form, and the way that we display objects within the GUI is by adding them to the form. That’s exactly what the code above does. We are defining a label that will become a part of the form. That label will be positioned at X=88, Y=73, and will contain the words Hello World.

In case you are wondering, it is the very last line of code in the code block above that adds the label to our dialog box form. The other lines of code simply define the label.

So the short explanation is that the script defines a form, and defines a button within that form. If the button is clicked, then PowerShell launches a function that adds a label to the form, and this label contains the words Hello World.

Conclusion

Now that I have walked you through the inner workings of a PowerShell GUI, it is time to make the GUI do something useful. We will start building a more useful script in the next article.

Leave a Comment

Your email address will not be published.

Scroll to Top