Skip to main content

Building Powershell GUIs that won’t freeze when you use them

A few days ago I wrote about how important I think it is that you build a GUI for your scripts if they are to be used by anoyone else.

If you have ever built a GUI using Powershell however, you know there is a problem with it that I didn’t mention, that is, whenever your script is actually doing anything the GUI will freeze and windows will tell you it isn’t responding. This is not good as most users will then try to close it and try again. We don’t want that.

The reason this happens is because you are running your form (GUI) and logic in the same thread, something you should never do, problem is, Powershells support for multithreading is limited at best.

In the last post I also talked about my module EasyGUI and mentioned that there are features I wouldnt go in to in that post, one of those features is an easy way to use threads.

There are two ways to use threads in EasyGUI, I go through both of them below as well as a tip on how I prefer to use them.

Method 1.

Passing in a scriptblock to the thread, here I am creating it on the fly but you could also store the scriptblock in a variable and pass that to the function instead

New-Thread {
    0..60|Foreach-Object{
        $SYNC.myLabel.Text = $_
    }
}

Method 2.

You could also write the code for the thread in a separate script file and then pass that to the New-Thread function like this

New-Thread "D:\Program\Powershell\myThread.ps1"

One thing to be aware of is that the threads will start running emediatly when you create them. Often you might not want that. What I usually do is create the threads inside a scriptblock that I store in a variable, then when I need the tread to run I run that scriptblock. That would look something like this.

$myThread = {
    New-Thread {
        0...60|Foreach-Object{
            $SYNC.myLabel.Text = $_
        }
    }
}

#Now it's time to run the thread, simply type the & sign and then the variable containing the scriptblock
&$myThread

$SYNC ? Where did that come from?

Noticed that did you?

This is a variable that’s automatically created when you initialize the EasyGUI module. It’s a hashtable that’s synced between all threads so you can communicate between them. In the examples you see that I am using $SYNC.myLabel. This is created in the GUI like this.

$SYNC.myLabel = New-Label @{
    Location = "15, 15"
}

or like this

$myLabel = New-Label @{
    Location = "15, 15"
}
$SYNC.myLabel = $myLabel

If you want to see a complete example of a GUI script with threading implemented there is an example availiable in the Easy GUI repository.

Share

Hello world!

Hello world!

There it is, my first blog post, isn’t it lovely? Really? you don’ think so? Well ok then, lets start over.

Hello there!

My name is Patrik Johansson and this is my blog.

I am a geek from Sweden that loves programming and scripting, especially for the web.  My passion for coding came relatively late, when I was 16 I took a java class at school. I struggled with the abstract way of thinking and really didn’t like it but I still wanted to learn how to program so the next year I once again took a programming class, this time PHP. After the first lesson I was in love and I started coding a lot in my spare time. I really can’t tell if I had just wrapped my head around the abstract way of thinking during the last year (doubt it) or if there was something else that made me love PHP.

One of the first real things we where told to code in my PHP class was a guestbook. I did but when I was finished I kept coding the rest of the evening and what I ended up with was a complete forum. Looking back at it now I am sure actually using the forum in a real life scenario would have been a very very bad idea, I was just starting out and security was nothing I had started thinking about. Still, back then it was amazing to me how quickly something like this could be done and how fun it was to do.

The next big(ish) thing I remember working on was a blog platform to use on my website. It actually turned out pretty good and I was even able to create a screen reader for it using a hidden API in google translate. I used the platform on my website for a couple of years without any big problems, about a year after I started using it on my website the comments stated beeing flooded by spam, I remember that one day I actually got over 500 comments on a single post, all of them spam. Ouch! This was a big milestone for me, it was here I started looking in to security for real, it started out with just preventing spammers from automatically spamming my site but ended up with real security like preventing SQL injections, slowing down brute force attacks, 2-way authentication and stuff like that. Well that’s a bit of a stretch actually, adding 2-way authentication is relatively recent for me, I’m a bit embarrassed to say that I started using it in my projects in the late 2013.

So how bout now?

Today I no longer have a favorite language but tend to use whatever I think will be the most suitable for getting the job done, be it PHP for web projects or java for android apps. And of course powershell for writing remote administration tools at work.

Most of the coding I do today that isn’t work related is on a project I call Booksonic, it is an android app for streaming audiobooks from your computer (or other server) to your phone and is forked from (based on) an app called DSub that does the same but for music. On the server side these apps connect to a server software called Subsonic. While Booksonic will work with the original Subsonic and all the forks of it out there for some of the Booksonic features you need more data from the server then it normally gives out. This means that I have also started working on a Subsonic fork called Booksonic Server.

Share