Create Powershell GUI with WPF

posted in: GUI, Powershell, WPF | 0

I recently switched to WPF to create graphical interfaces for my tools.
In this post I will show you a very simple way of creating the GUI using Visual Studio.

Previously I was using WinForms and creating everything manually and eventually, I got tired of this since it took a lot of time.
I’ve also tried to use Powershell Studio but since that is a product that is not free of charge and WinForms is getting old I felt like this was a good transition.
The switch to WPF really sped things up for me and made my tools look really fresh and modern.

guiexample_1

The GUI that I will build here will look like this.

It is very simple and ugly but it will be enough for this post. 🙂
It will run a function when you click “Get Info” and display your Windows product name in the textbox.
The button Close will only close the window.

Requirements

To build the GUI you will need the following.

  • Visual Studio. Any version is fine as long as you can create a new WPF Application.
    • Visual Studio Express should suffice.
  • Powershell ISE
    • Powershell version 2 or later.

Lets begin!

Start by opening up Visual Studio and select to create a new WPF Application.

Design your GUI as you wish. You can do this by expanding the Toolbox on the left side of the window and drag and drop them on your application.
I used two labels, two button and one textbox in my GUI.

In the bottom of Visual Stuide you will se a tab called XAML.
This tab contains all the information required to create the GUI. My XAML code looks like this.

Copy all text from the XAML tab and paste it into Powerhell ISE

It should look like this in ISE.

xamlcode

To make this work in powershell there are a few things we need to edit the the code.

  • Find the row with x:Class= and delete it and everything that follows. You want to keep <Window. In my example this is row one.
  • Delete the following rows.
    • xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
      xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
      xmlns:local=”clr-namespace:Get_ComputerInfo”
      mc:Ignorable=”d”
  • Search and replace all instances of x: with nothing.

Now it should look like this.

To make this readable by powershell you have to add the following code.
Insert this code above the XAML.

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')

$XAML = @’

And insert this code below the XAML.

'@
#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================

$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}

#===========================================================================
# Shows the form
#===========================================================================
$Form.ShowDialog() | out-null

This will read your XAML and make powershell able to open it. This will also create vaiables from all your objects so you can assign values and functions to them.
At this point your code should look like this.

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')

$XAML = @’ ‘@ #Read XAML $reader=(New-Object System.Xml.XmlNodeReader $xaml) try{$Form=[Windows.Markup.XamlReader]::Load( $reader )} catch{Write-Host “Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered.”; exit} #=========================================================================== # Store Form Objects In PowerShell #=========================================================================== $xaml.SelectNodes(“//*[@Name]”) | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)} #=========================================================================== # Shows the form #=========================================================================== $Form.ShowDialog() | out-null

You can now run your script and it should open a GUI that looks like your application from Visual Studio.

All we have to do now is to add some powershell code to actually use the application.

Insert the following code after the row containing $xaml.SelectNodes(“//*[@Name]”) | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}.

#===========================================================================
# Declare script variables
#===========================================================================

$Script:CompInfo = ""

#===========================================================================
# Declare script functions and controls
#===========================================================================

# Get computer information and set the value of the textbox.
function Get-Info {
$Script:CompInfo = Get-ComputerInfo
$txtProdName.AppendText($Script:CompInfo.WindowsProductName)
}

# Enable the Get Info button to run the function Get-Info.
$btnGetInfo.Add_Click({Get-Info})

# Enable the Close button to close the window.
$btnClose.Add_Click({$form.Close()})

The comments in the code should explain to you what each row does and why.
By running the script now you will get a window to open and you can click Get Info to get the Windows version to show in the textbox.
click Close when you are done.

I hope this will help you to create your first GUI and move on to make some awesome tools.

Leave a comment if you have any questions and I will try to answer or explain as best I can.

/ Niclas

Leave a Reply

Your email address will not be published. Required fields are marked *