If an error occurs in a WinForms GUI PowerShell script, you can display an error message in a status bar.

When building scripts in PowerShell, it’s common practice to surround code in a try/catch block and throw an exception whenever an error occurs. When this exception is thrown, the code can either do something with that exception or send the exception out to the console to notify the person who executed the code. When building a Windows Forms (WinForms) GUI in PowerShell, however, you can still use the try/catch block, but you need to rethink the way you notify the person executing the code. Why? Because you have no console.

GUIs are useful for many purposes, but people who are used to building scripts in PowerShell are probably much more comfortable writing command-line scripts. This is, after all, what PowerShell is all about. But due to PowerShell’s integration with the .NET framework, you can do so much more than simply build command-line scripts.

By using WinForms and some .NET, it’s easy to build a nice-looking GUI. Because of the nature of PowerShell, most people who have written code in PowerShell for a while take for granted that the console will always be available. For me, it’s second nature to put a Write-Verbose, Write-Warning, or Write-Error reference in my script. When you’re building a GUI though, you don’t have this luxury. You must figure out how to indicate to the user of your script that an error has occurred.

A multitude of ways exist to handle errors in your WinForms GUI scripts, but I tend to focus on only one: catching and displaying errors in a status bar. Let‘s go over how to do this.

First of all, we‘ll need a basic form to which we can add controls.

Add-Type -AssemblyName System.Windows.Forms
 $Form = New-Object System.Windows.Forms.Form

Then we can create a status bar and add the status bar with a simple message.

$statusBar = New-Object -TypeName System.Windows.Forms.StatusBar
 $statusBar.Text = ‘Message status bar’
 $Form.Controls.Add($statusBar)
 $Form.ShowDialog()

Once we do this, we’ll have a simple form with a single status bar.

Simple form with a single status bar

Simple form with a single status bar

Now add a button to give an example of a control where an error might occur when clicked.

Form with a submit button

Form with a submit button

Then we can add some code to execute when the button is clicked.

$button.add_Click({
     Get-Content -Path C:\File.txt
 })

This will attempt to get the contents of the C:\File.txt file when the button is clicked. But what if the file doesn’t exist? If you run this now, an error will be shown on the console.

Error shown in console

Error shown in console

Although this is good when testing the script, if you’re building this for someone else, you’re most likely going to give this to them in a compiled EXE file. In that case, nothing will be displayed in the form. You need a way to catch this error and put that error message in the status bar.

To resolve this problem, you might put a try/catch block in the scriptblock to catch and set the status bar text to the error message.

$button.add_Click({
     try
     {
         Get-Content -Path C:\File.txt
     }
     catch
     {
         $statusBar.Text = $_.Exception.Message    
     }
 })

However, you’d find that this does not matter, because for the exception to be thrown into the catch block, Get-Content must throw a terminating error and, by default, it throws a non-terminating error. Once you do this, you will see the error message show up in the status bar rather than on the console.

Error message shown in the status bar

Error message shown in the status bar

Other cmdlets produce terminating errors naturally. Dealing with terminating and non-terminating errors is another task you must do via the command line. However, in the GUI, you must ensure not only that the exception gets into the catch block but also that you set the status bar text property rather than simply calling Write-Error, for example.

Subscribe to 4sysops newsletter!

This is just a simple example of error handling while building WinForms GUIs and does not apply to all situations. However, it proves a good example of how to use try/catch blocks to catch errors and then set various GUI control properties in order to display the error to the user.

 

0
3 Comments
  1. Chris 3 months ago

    I've been using this method for a while now and it was working fine.  With PowerShell 7 though, I'm now getting the error "Cannot find type [System.Windows.Forms.StatusBar]: verify that the assembly containing this type is loaded."  Is there a new way to do this?  Thanks!

    0

  2. That's not an option for you in later versions of .Net

    https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.statusbar?view=netcore-3.1

    But you can use a StatusStrip https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.statusstrip?view=net-5.0 (not sure how similar it is graphically)

    David F. 

    +1

  3. Adam 2 weeks ago

    How can I reset the status message each time the button is pressed. So when the user clicks on the button after the file is found the message will clear?

    Thank you love the guide.

    0

Leave a reply

Please enclose code in pre tags

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

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account