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)
 Sunday, June 28, 2009

Codestock 2009 wrapped up last night.The event was oversold by 1 - 376 attendees. I enjoyed the selection of talks that were available, and the sessions I attended were good. Of course I had a favorite.

My Favorite session was delivered Rik Robinson of Wintellect. His talk was on PRISM, from the Microsoft Patterns and Practice group (PNP), this is a Guidance that can be used in WPF and Silverlight - and incorporates the Unity IOC framework (but that can be swapped out if you prefer). He kept it simple, he introduced one thing built on another, and he got the main concepts of how PRISM can be used to develop applications that decouple View and ViewModel in a very clean fasion. The session was very interactive and it must have been a bit of pressure to have the Wintellect CEO sitting in the session.

Through another acquaintance I got to have dinner with Rik that night(day of his presentation), and hooked up with him for yet another dinner after the last Codestock session before driving back (we did not attend the giveaways).

Wintellect is local to Knoxville, and is one of the supporters of Codestock. They arranged to have to other presentations besides Rik Robinson's. John Robbins and Jeffrey Richter gave presentations via live meeting - and took questions via cell phone (which you would hear in the room as an echo - but it worked). I attended the John Robbins debugging presentation and it too was excellent (he can make technology humourous) - I picked another session instead of the Jeffrey Richter session - if they recorded it I am going to go watch it.

I feel a bit responsible for a comment from another attendee about one session I attended. The session just seemed like there were more examples that were ready - but not shown - and the session ended earlier than the time slot. I overheard someone else make that comment about it - and it seemed to fit. I had been fine with how it was -and only when I heard the comment did it occur to me that not all of the examples had been touched on. I had sat down to lunch with this speaker before his presentation. It occurred to me that I may have impacted his preparation, and even the thought that I did impact his presentation makes me feel sorry for having disturbed his preparation. I felt it was still a good presentation. I heard how much Rik Robinson prepared and saw the result - it is a lot of work - and it makes me wonder if my trying to be social - was just at the wrong time (My apologies to the speaker)

There were several topic areas of interest for me during codestock. WPF,PRISM, MEF, Debugging, WCF, ORM usage, and TDD. There were sessions that touched on, or spoke to these - and much more.

Another acquaintance suggested I attend Kevin Hazzard's session on "How I learned to love Metaprogramming" - which was a very good look into the way that the compiler creates a dynamic data type in .Net 4.0. The data type of dynamic - is static. That statement seems at first to be an oxymoron - but the element is treated as static and how it resolves at runtime is dynamic. The presentation showed how C# and Python could interact - and gave some examples of dynamically wrapping elements of XML using C# using the Dynamic elements. His XML Example reminded me of something that Powershell can do today - and Kevin said that the powershell team did not go down the Dynamic Language path - which he was not pleased with. Kevin Hazzard is a very good speaker and he gets into the topic very deeply - and explains it well. I would like to hear more about his perceptions on Powershell, and how he thinks it might have been done.

There was one connection that I did not expect to occur. At the CodeStock social event, I was sitting at a table, and a fellow walked over and looked at me and said - I think I know you. After a moment or two - I recogognized him from a twitter photo. When I went to Devlink 2008 - I was trying to use Twitter to find out where people were meeting up, and I had been on twitter for maybe a month at that time. This fellow was not able to attend the DevLink event - but was trying to follow what was going on - and he responded to help me figure out where people would be. Between this fellow and "TheCodeCampJunkie" - I was able to hook up with people at DevLink. So here was my first time meeting a person face to face - based on using twitter. We talked about .Net and his getting certified and how it was not helping him get work.

The main focus of these event is the dissemenation of knowledge of what is new and how to use the technology we deal with. The other part of this is that you are meeting and speaking with other developers, whom you may have not ever met otherwise.

Several people have posted pictures from CodeStock - Alan Barber got one picture of me at the Dinner on the night before the event.

Sunday, June 28, 2009 7:37:48 AM (Eastern Standard Time, UTC-05:00)
 Friday, September 05, 2008

The two code camps that I attended in August, CodeStock and Devlink, were certainly enlightning.  The contacts that I made have been kept alive via the twitter traffic that I receive. I work for a company that does not allow for twitter connections from a company computer. So I connect when I am on my personal laptop. I check the blog sites for the contacts that I made there, as it gives me an insight into their thinking too.

I have also used LinkedIn to connect with some of the developers who attended this. I have learned how networking can be a vital aspect of finding opportunities for technical events, social events, technology information, and professional opportunities.

The CodeCamps have a good set of attendee's who are developers who are trying to improve their skills and knowledge, and these are the types I enjoy working with in both my professional and personal relationships.

I am still amazed at the level of expertise that I encounterd in these codecamps - and I would reccomend anyone to attend them when they can.

 

Friday, September 05, 2008 4:17:15 PM (Eastern Standard Time, UTC-05:00)