Use ShowUi to Easily Create Graphical Interfaces for PowerShell

Use ShowUi to Easily Create Graphical Interfaces for PowerShell

  • Comments 2
  • Likes

Summary: Use ShowUi, a free Windows PowerShell module, to simplify creating graphical interfaces for scripts.

 

Microsoft Scripting Guy Ed Wilson here. Today, I have a guest article from my good friend James Brundage. Here is a little bit about him.  

James Brundage is the founder of Start-Automating, a company dedicated to saving people time and money by helping them automate. Start-Automating offers Windows PowerShell training and custom Windows PowerShell and .NET Framework development. James formerly worked on the Windows PowerShell team at Microsoft. You can follow James on Twitter (@jamesbru) or on the Start-Automating company blog.

Take it away, James!

 

Some people say I love Windows PowerShell a little too much.

I strongly believe that a script a day keeps Dr. Scripto away. I easily spend more time scripting with PowerShell than any other recreation activity (except maybe Xbox), and I take any statement along the lines of “you can’t do that in Windows PowerShell” as a challenge.

Today, I’m going to showcase an answer to one of those “you can’t do that in Windows PowerShell” lines.

An astoundingly large number of people don’t know that you can write user interfaces in Windows PowerShell. Some small technical changes in Windows PowerShell 2.0 enabled scripting of a really cool UI platform called Windows Presentation Foundation (WPF).

In June 2011, scripting WPF reached a whole new level of easy with the release of ShowUI. ShowUI is a Windows PowerShell module that makes it simple to write UI in Windows PowerShell with WPF. You can download ShowUI at http://showui.codeplex.com/. Now, not only can you write user interfaces in Windows PowerShell, but they’re almost always a lot shorter.

In This Weekend Scripter article, I’ll show and explain a fun sample: How to Write a Drag-and-Drop Video Player in 12 Lines of Script. Here’s the code:

New-Window -AllowDrop -On_Drop {

    $videoPlayer.Source = @($_.Data.GetFileDropList())[0]

    $videoPlayer.Play()

} -On_Loaded {

    $videoPlayer.Source = Get-ChildItem -Path "$env:Public\Videos\Sample Videos" -Filter *.wmv |

        Get-Random | Select-Object -ExpandProperty Fullname

    $videoPlayer.Play()

} -On_Closing {

    $videoPlayer.Stop()

} -Content {

    New-MediaElement -Name VideoPlayer -LoadedBehavior Manual

} –asjob

 

It’s a pretty simple app. I create a window, and I allow it to accept dropped items. Whenever an item is dropped (On_Drop), I look into that items data and get out the list of files. Then I select the first one, and make the video player’s source that item. Then, I start up the video player.

Whenever a window is loaded, I go find all the sample videos, pick a random one, and make that the video player’s source. I then start the video player. Whenever the window is closing, I make sure to stop the video player as well, or else the media actually keeps playing in an invisible window. The window only has a little bit of content. That content is a media element called VideoPlayer. This MediaElement is what’s providing the value for $videoplayer everywhere in the script. Because we want to be able to stop and play the video manually, I set LoadedBehavior to Manual. To make sure that I can watch the videos and script at the same time, I launch my UI in the background with –AsJob.

ShowUI lets you build richer solutions than you ever thought possible with Windows PowerShell. Download it for yourself at http://showui.codeplex.com/, and keep watching our YouTube channel for more videos. And the next time a colleague of yours doubts the power of Windows PowerShell, just say:

“Hey, I’ve got a little video to show you.”

 

Splatting and ShowUI

Splatting is a nifty technique that lets you use a hash table as the input for your scripts or cmdlets. I cover this in greater detail in A Series on Splatting (Part 1, Part 2, Part 3, Part 4, Part 5).

This example shows how we can make a frontend for the world’s simplest function: Out-LastNameFirstName. Watch the YouTube video.

Import-Module ShowUI

 

function Out-LastNameFirstName

{

    param($firstName,$lastName)

   

    "$lastName, $firstName"

}

 

$in = New-UniformGrid  -Columns 2 -ControlName Get-FirstAndLastName -Children {

    'First Name'

    New-TextBox -Name FirstName

    'Last Name'

    New-TextBox -Name LastName

    ' '

    New-Button "OK" -IsDefault -On_Click {

        $parent | Set-UIValue -passThru | Close-Control   

    }

} -show

 

Out-LastNameFirstName @in

 

The function is simple enough. Out-LastAndFirstName will simply print out a firstName and lastName packed together in lastName, firstName format. The UI is also really simple, because of the magic of ShowUI.

$in will set the window’s value when we close. A UniformGrid is a control that will automatically put items in a uniformly arranged grid. By giving the grid two columns, I can guarantee that the odd-numbered items go on the left and the even-numbered items go on the right.

The grid has a ControlName: Get-FirstAndLastName. –ControlName is a parameter in ShowUI that lets you anchor all of the values to a particular part of the UI. –ControlName helps determine which variables are there in your event handler, and where the UI will get values.

‘First Name’ is just a string, and, if you put a string inside a collection in ShowUI, it will automatically try to turn it into a label. The text box comes right after it, and will appear on the right side. By giving the text box a name, two things happen: 

  • A variable $FirstName will appear in all of the event handlers pointing to that object.
  • Whenever we go to output the value of Get-FirstAndLastName, it will create an entry in a hash table which contains the text in the text box. 

The  ‘  ‘ simply forces a space. This just helps alignment within the uniform grid. The OK button is where the magic is. When it is clicked, the automatic variable $parent (which points to the nearest –ControlName) is piped into a command Set-UIValue. At this point, Set-UIValue creates a value for the control based on what was typed in the text boxes.

 

Thanks again to James Brundage! I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hello James,

    a pretty good thing ... this ShowUI module!

    And a good example of how to get into touch with it.

    I'd really like to be able to create a simple GUI with Powershell in a couple of lines,

    but it is a pity that the underlying WPF module is that slow!

    In our company most coworkers have standard PCs with at most the cheapest 2 core CPUs

    and it really is hard to wait 10 seconds before the UI shows up ... :-(

    But nethertheless it is a good idea to stay in touch with WPF and ShowUI .... great work!

    Klaus

  • Hey Klaus

    Could you say a little more?

    ShowUI ought to be slow only the first time you use it. It does some up front optimizations and should be faster on subsequent uses even after closing an opening the console, ISE etc.

    Using the AsJob parameter will run a bit slower compared to using Show because it has more work to do to run it as a background job.

    Thanks

    Doug

    http://dougfinke.com/blog/