Saturday, October 09, 2010
The September meeting of the Atlanta Powershell User group was to be about Scripting GUI with PowerShell. Mark Schill, the leader of the group, indicated that if no one else  volunteered,  he would do it. The September meeting was cancelled due to the short time allowed for the topic, and I asked if anyone had volunteered. No one volunteered, and the topic was one I was interested in - so I volunteered for the October meeting presentation on Scripting GUI with PowerShell. This post reflects the research I did for the presentation.(Apologies to the group for posting this weeks after the presentation).

A "Graphical User Interface" or GUI, is to present a Graphical window to display data visually, or gather information from direct user input. Doing this from script means that it is not compiled into a frozen format, and that gives you  flexibility to change things quickly without recompiling a standalone program.  If you are providing your script for someone else to use - and they are more comfortable with point and click - creating a GUI is in one way to bridge that gap. If you are trying to isolate what a user can do within Powershell - building an application with the Powershell SDK as a standalone program might be a better option; but that also would be freezing the presentation format. With Powershell this is great - as you have options, and the issues are - that you have options - you have to figure out what you are trying to accomplish, and how, if you even want PowerShell script run with a GUI interface you have lots of options.

One key thing to point out is that, using version 2, Powershell console and the Powershell_ISE work differently in their execution threading model (this goes back to COM components and how they deal with threads) - that impacts doing a GUI  as there are Windows components that require a Static Threaded Aparment (STA) model, and will have issues with Multi-Threaded Apartment (MTA). Powershell console,  by default, is an MTA application - each command is its own thread. Powershell ISE by default uses an STA model. You can force Powershell console to start with the STA mode by adding a parameter -STA on the command line. Create a shortcut with the -STA parameter if you are planning on using the Console to spin up a GUI. Your other option is to run powershell from within powershell on an STA thread - Oisin Grehan wrote a post on how to do that.

When it comes to presenting a GUI from Script, there are options, which comes down to COM objects,Winforms, and WPF at the root of any GUI interface. COM objects that can accept data for presenting information, Winforms and WPF for user input. So I will review this in terms of "Data Presentation" and "User Input".

Data Presentation


PowerGadgets
One presentation option that starts with the Vista OS, is the Gadgets bar. There is a suite of tools that uses the Gadget bar called PowerGadgets -"Professional IT monitoring for under $100" which offers Gauges, Maps, and Graphs for use from powershell. However one blogger, James O'Neil, indicated that it was not well documented and has some issues. (Since my employer has not moved past XP, I am not able to comment from my experience).

Microsoft Chart Controls
One option that bloggers Richard MacDonald, and Chadwick Miller(aka Chad Miller of SQLPSX) write about is using MS Chart from Powershell. You have to download and install the Microsoft Chart controls for Microsoft .Net Framework 3.5 components, and it does require that you have .NET 3.5 SP1. Microsoft made these objects available as a download - and the Charting objects are provided as part of the .Net Framework 4, Microsoft acquired these charting controls(Visualizations) from Dundas, so these should be standard from now on. (The 3.5 download may not have the same number as the .Net 4 framework.)

In the approach of data presentation using the MSChart approach, you may have to understand the data binding. Alex Gorev, who worked for Dundas, and now for Microsoft, blogged on the Databinding with the controls. Chad Miller's post help make the transition of that information to Powershell - he created a function LibraryChart on PoshCode that encapsulates using the MSChart library.


PoshBoard
(Powershell Dashboard)
One open source option for Data Presentation  is Poshboard - that uses Silverlight and PowerShell and the Visifire components. Poshboard has posted some great previews of what is being worked toward. From France, Antoine Habert is the developer - who says he is just a scripter. He has posted some videos on the versions he has released for Poshboard. Version 3.0 beta version multitouch video, and the video demo of the stable release of version 2.5 - but at this point in October of 2010 - you cannot build this - with Visual Studio 2008 you must install the 3.0 Silverlight extensions (at least) and there is work being done on the 4.0 extensions (no audio on either video for 2.5 or 3.0)- but you get the idea of what is going on!). I tried to follow instructions on this - with a Visual Studio 2008 SP1 on XP and could not get it to work locally. Antoine Habert's Posbhoard work attracted the attention of PowerShell architect Jeffrey Snover (Poshboard was noted in his post on ConvertTo-Hashtable). With RIA Services and Silverlight on the desktop, it will be interesting to see how this progresses. This has potential that may not be easy to appreciate at this point - but has a huge potential -the churn effect of various pieces will hopefully be worked out). I would recommend following up on this project as I think it could have great value if it presents a stable installation set of instructions that works(for XP,Vista,Win7 and Server editions).

Data Interaction

Winforms and WPF are the two pieces of the .Net framework that make creation of a GUI possible from PowerShell. Winforms was the basis of the Graphical User Interface within Windows for years. The .Net framework encapsulated the Winform API in the System.Winforms.Form namespace. WPF came along with .Net 3.0 and the System.Windows.Window namespace (actually a few more than just that). These two namespaces provide the core functionality to interact with the user to capture data input from a script - if that is how you want your script interaction to operate. This does provide the flexibility of the script - and changing it as needed - pretty much on the fly - instead of re-compiling into a fixed format. The key to using these interactions - is to create an object that you add properties to within the script so that the data is available from the pipeline after the GUI interaction. The Powershell ISE exposes its script object model to the users to extend - and the Powershell ISE is a WPF application written with the Powershell SDK. So there is a great deal more control if you want to get to that level of creating a GUI for powershell. For the purpose of the presentation - and it's audience - I have tried to limit the topic to "Scripting a GUI" - as not everyone will do work in Visual Studio - Powershell scripting can be done independent of Visual Studio - and so there are areas that Developers may be familiar with, in terms of API that non-developers might find as a learning curve to work with.

Winforms

Winforms from Powershell depends on the namespace of System.Windows.Forms to gain access to the Win32 API pieces through the .Net framework. It is the API layer that gave us the windows that started years ago - built into the Windows OS. The details of the .Net usage and translating it to PowerShell is where a bit of the work lies (and that holds true for WPF too).

Bruce Payette's Powershell in Action (1st edition - Powershell 1) gives scripts that use the  WinForms abilities to put a screen before you as a user. His scripts show that it can be done, and that the details are not small to put up a GUI for data interaction. Lots of fine tuning is required in putting together a decent GUI when it starts to become complex. There is a basic set of controls provided with the 1st Edition of "Powershell in Action" - and you may find that you don't need much more than what he worked to create for his readers. If you keep things simple this is a workable solution.

Winforms from PrimalForms

Sapien Technologies created their PrimalTools.com for their tools. They have produced some Free tools and one of those is Primal Forms community edition (Free) and a professional version (currently about $150) of Primal Forms. The Free edition allows for drag and drop creation of a screen layout - and to have it take care of the fine details of the layout for free is great - but you have to figure out how to hook your scripts into the script output yourself. The Primal Forms professional edition states that you can put your scripts into events - so you don't have to figure it out on your own - and that alone could make this pay for itself. (If you are doing lots of GUI's in a winforms style, this could be a very good tool to invest in).

WPF

WPF is from the System.Windows.Window Namespace - and is possible from .Net 3.0 and afterward. The direction for the UI space from Microsoft seems to be heading toward a WPF type interface now  - Visual Studio 2010 and the Powershell ISE are good examples. Microsoft has worked on the performance of WPF as it brought out VS 2010.

WPK  
As the powershell team was working toward releasing version 2, one of the testers, James Brundage, was working on a way to use WPF from powershell - this was released as "WPK". My earlier post on learning from Powershell extensions ties right back to this idea - the Windows PowerShellpack includes the WPK PowerShell extension that gives you the basics to build a WPF screen. James Brundage, who has since left Microsoft, produced this code. It is workable however the load time is slow.


Powerboots
I recall reading Jeffrey Snover's blog post about this module, just after Jan of 2009, and was initially fascinated that someone was trying to do GUI's with WPF in powershell. I read about the basis being on the ruby "Boots". I tried an early download but it did not work for me. While I was working on the presentation, I mentioned this to Mark Schill, and he told me to Contact Joel Bennet- (who developed Powerboots), and he would help me - I did that via his website HuddledMasses.org - and I did get Powerboots to work.

If you do not see a full release of Powershell dated AFTER October 2010, you should download the latest software uploaded to the CodePlex site. You unzip that under your Powershell Modules folder (under your documenents/WindowsPowershell) and then rename the mangled name to be just PowerBoots. Then go into the bin folder and rename the PoshWpf.dll - to OLDPoshWPF.Dll   - then rename one of the other DLL's for PoshWPF to what you have on your system.

Joel 'JayKul' Bennet is a Powershell MVP, and certainly has earned it. He is working on Powerboots and improving its performance. He actively participates in the IRC Channel #Powershell. His working machine is a 64bit machine and working with .Net 4 - and that was part of the issue I had - working on an XP machine 32bit and only .Net 3.5 on my demonstration machine. A few instructions after contacting him, and I was generating windows with Powerboots.

There is a Samples.ps1 in the Powerboots/Samples directory - and that will have enough basic examples to show you what you can do with Powerboots. 

Joel Bennet had made a post of some code  I had an issue with - that he corrected and reposted during an IRC chat with him.  You can create XAML as an external file and use that in Powerboots if you want to - You do not have to create your XAML outside to use powerboots. This example was one I wanted to see how you could create your XAML in a tool designed for that, and then use that from your script. (Joel's original post of the script code). If you go to his Original post you should save the XAML to your local environment - and I saved mine in my "C:\Data\" folder and then point to that in the script.
You  see a very key piece in the script  - the use of the new-object followed by Add-Member using the pipeline.
That adds properties by name to the base object - very much the way that you can use Javascript prototypes - you can add Properties and Methods to Powershell objects. (You have to do 'Import-Module powerboots' to run the script below).

####################################################################################################################
## Create the window and hook the click. Make sure to use full paths
function Calculate-TripCost {
$result = new-object psobject
$result | Add-Member -type NoteProperty -name Cost -value 0
New-BootsWindow {} -FileTemplate C:\Data\Boots_MainWindow.xaml -On_Loaded {
#If you get an old version of Boots you wont have this
Export-NamedElement
$Calculate.Add_Click({
$Total.Text = '${0:n2}' -f (($Miles.Text -as [Double]) / ($Mpg.Text -as [Double]) * ($Cost.Text -as [Double]))
$result.Cost = $Total.Text
$BootsWindow.Close()
})
}
$result
}
Calculate-TripCost


The $result field is returned to the pipeline so it can be used after the function has completed.
You can create multiple properties to hold on to the UI elements. This would be the same tactic done with Winforms - so that you can use the data you capture.

Powerboots, using WPF, can do Transparent Windows - which allows you to create a control or test message on your desktop that has information - which seemed to be like PowerGadgets without writing to the API for Gadgets. Powerboots is a very active Codeplex project -and is preparing for a new release that will be far more performant that WPK and with a clean syntax. Powerboots will probably become the de-facto method of producing WPF GUI's from Powershell, as it has coverage for Graphics, DataInteraction, and has the performance. There is work is being done to make it work with .Net 4. I would keep an eye on this extension as it has great value potential long term.


That gives you a high level rundown of some GUI approaches for Powershell - and I hope that is helpful.

I have tried to package up what I presented in the zip file - you need to unzip it using folder names it expects to have a C:\PS1 and C:\Data folder on the machine for the script to run. You need to go to the PS1 directory using a Console window started with the -STA parameter and then use .\Start-Demo DemoIntroToGUIScript.txt - you have to have done the downloads for WPK, Powerboots, and MSGraph mentioned in this post for parts to work.


 


PowerShell_GUI_Demo.zip (38 KB)
Saturday, October 09, 2010 5:33:18 AM (Eastern Standard Time, UTC-05:00)
 Wednesday, November 05, 2008

I found a link tonight that led to a Codeplex project http://www.codeplex.com/cracknetproject.

From the Codeplex site

Crack.NET is a runtime debugging and scripting tool that gives you access to the internals of a WPF or Windows Forms application running on your computer. If you love Snoop and Mole for Visual Studio, you’ll love Crack.NET, too. Crack.NET allows you to “walk” the managed heap of another .NET application, and inspect all values on all objects/types.

This looks like a good tool in becoming familiar with what is going on in WPF and Winform apps.

 

 

Wednesday, November 05, 2008 10:04:02 PM (Eastern Standard Time, UTC-05:00)