Creating a Windows Form in PowerShell

February 16, 2012 at 8:36 am 5 comments

The script here is a demonstration of how PowerShell can be used to create .NET objects such as Windows forms.  This code creates and builds a GUI along with button click events.  As a demonstration it is designed to read a csv file (using the Open File Dialog box to locate it) and work with controls on the page.

 

# Demonstration code to create a .NET Windows Form, populate it with controls and use it
# to read and process a file.

# Load the .NET Assemblies
[void][System.Reflection.Assembly]::LoadWithPartialName(“System.windows.forms”)
[void][reflection.assembly]::LoadWithPartialName(“System.Drawing”)

function LoadCSV(){
# Clear any items that may exist in the lists.
$count = $form.Controls[“lstNames”].Items.Count – 1
for ($i = $count;$i -ge 0;$i–)
{
$form.Controls[“lstNames”].Items.RemoveAt($i)
$form.Controls[“lstEmails”].Items.RemoveAt($i)
$form.Controls[“lstphones”].Items.RemoveAt($i)
}

[System.Windows.Forms.OpenFileDialog]$ofd = New-Object System.Windows.Forms.OpenFileDialog
$ofd.ShowHelp = $True
$ofd.Filter = “CSV Files (*.csv)|*.csv|All Files (*.*)|*.*”
if ($ofd.ShowDialog() -eq “OK”)
{
$details = Import-Csv -Path $ofd.FileName
foreach ($line in $details)
{
$form.Controls[“lstNames”].Items.Add($line.Name)
$form.Controls[“lstEmails”].Items.Add($line.Email)
$form.Controls[“lstphones”].Items.Add($line.Phone)
}
}
}

function ProcessDetails()
{
Clear-Host
for ($i = 0;$i -lt $form.Controls[“lstNames”].Items.Count;++$i)
{
Write-Host $form.Controls[“lstNames”].Items[$i] ” – ” $form.Controls[“lstEmails”].Items[$i] ” – ” $form.Controls[“lstphones”].Items[$i]
}
}

function BuildForm()
{
#Create the form
$form = new-object Windows.Forms.form
$form.Size = new-object System.Drawing.Size @(800,300)
$form.text = “Demo Form created with PowerShell”

#Create the buttons
$btnLoadCSV = New-Object System.Windows.Forms.Button
$btnLoadCSV.Width=100
$btnLoadCSV.Location = New-Object System.Drawing.Size(350, 10)
$btnLoadCSV.Text = “Load CSV File”

$btnProcessCSV = New-Object System.Windows.Forms.Button
$btnProcessCSV.Width = 100
$btnProcessCSV.Text = “Process CSV Data”
$btnProcessCSV.Location = New-Object System.Drawing.Size(350, 35)

#Create the list boxes and their assosciated labels.
#Names
$lblNames = New-Object System.Windows.Forms.Label
$lblNames.Text = “Names”
$lblNames.Location = New-Object System.Drawing.Size(50, 75)

$lstNames = New-Object System.Windows.Forms.ListBox
$lstNames.Name = “lstNames”
$lstNames.Width = 200
$lstNames.Height = 100
$lstNames.Location = New-Object System.Drawing.Size(50, 100)

#Email addresses
$lblEmails = New-Object System.Windows.Forms.Label
$lblEmails.Text = “Email Addresses”
$lblEmails.Location = New-Object System.Drawing.Size(300, 75)

$lstEmails = New-Object System.Windows.Forms.ListBox
$lstEmails.Name = “lstEmails”
$lstEmails.Width = 200
$lstEmails.Height = 100
$lstEmails.Location = New-Object System.Drawing.Size(300, 100)

#Phone numbers
$lblPhones = New-Object System.Windows.Forms.Label
$lblPhones.Text = “Phone Numbers”
$lblPhones.Location = New-Object System.Drawing.Size(550, 75)

$lstPhones = New-Object System.Windows.Forms.ListBox
$lstPhones.Name = “lstPhones”
$lstPhones.Width = 200
$lstPhones.Height = 100
$lstPhones.Location = New-Object System.Drawing.Size(550, 100)

#Add the controls to the form
$form.Controls.Add($btnLoadCSV)
$form.Controls.Add($btnProcessCSV)
$form.Controls.Add($lstNames)
$form.Controls.Add($lstEmails)
$form.Controls.Add($lstPhones)
$form.Controls.Add($lblNames)
$form.Controls.Add($lblEmails)
$form.Controls.Add($lblPhones)

$btnLoadCSV.add_click({LoadCSV})
$btnProcessCSV.add_click({ProcessDetails})
return $form
}

$form = BuildForm;
$form.ShowDialog();

Entry filed under: PowerShell.

NetComm NP206 Wireless Powerline Kit Where does PowerShell look for Modules

5 Comments Add your own

  • 1. Joel  |  September 11, 2012 at 5:40 pm

    error received on line 11 char –
    for ($i = $count;$i -ge 0;$i–)

    Reply
    • 2. Brent Challis  |  September 18, 2012 at 11:04 am

      The for loop needs a double hyphen to decrement the counter. The line:
      or ($i = $count;$i -ge 0;$i–)
      needs to be:
      or ($i = $count;$i -ge 0;$i-–)

      Can you try this to see if it works?

      Reply
  • 3. Philip  |  October 6, 2012 at 12:15 pm

    Hi, I tried this (with the — as suggested) and it works. However, when importing a simple csv file (name,name@email.blah,123456) I see the following:
    Exception calling “Add” with “1” argument(s): “Value cannot be null.
    Parameter name: item”
    At T:\Scripts\Powershell\LoadCSVwithForm.ps1:26 char:2
    + $form.Controls[“lstNames”].Items.Add($line.Name)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

    Just learning PS and seeing what can be done with forms. Am competent VB, VBS and VBA (especially with MS Access) but PS downright confuses me 🙂

    Reply
    • 4. Brent Challis  |  October 9, 2012 at 12:18 pm

      In my code I have used specific values for the names of the columns in the csv file. If you have changed the column headers or the code then you will get null values back. On of the ways that PowerShell works is that is tries to be helpful so often when you reference something that it can’t find, rather than giving an error it returns a null and keeps trying to work.

      Reply
      • 5. Philip  |  October 9, 2012 at 1:24 pm

        OK got it. Didn’t realise that the CSV required the first line to be a header and contain the names as in the script.

Leave a comment

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendar

February 2012
M T W T F S S
 12345
6789101112
13141516171819
20212223242526
272829  

Most Recent Posts