Posts Tagged ‘PowerBoots’

I’ve finally given over trying to improve PowerBoots for this iteration of development, and in between setting up the ScriptingGames.PoshCode site and releasing the PoshCode software on the main PoshCode.org site (it’s coming, I promise), I decided to take a few minutes and release this lates PowerBoots, and it’s a ground-breaking release, if I do say so myself!

PowerShell 1.0 Compatibility

There are three huge changes in this release, actually. But the biggest one is that most of the functionality works in the released version of PowerShell 1.0! There are still a few glitches and bugs when it’s running in 1.0, but I’ve decided it’s past time I just release it and let you start using it! If you use it on 1.0, please let me know if you run into anything weird, or problems you can’t figure out workarounds for.

Cached Script Functions!

The second biggest change is that all of the functions are now cached. The first time it’s loaded, PowerBoots actually writes out a few hundred scripts files into a “Functions” subfolder, and from then on, they’re only loaded when they’re used — saving you a lot of time at startup, and a lot of memory. Additionally, when you load in additional controls, such as the Visifire WPF chart controls, those functions are cached permanently too, so you never even have to manually load the assembly again!

Dependency Properties

A few people have asked over the last few months about how to set attached properties and dependency properties in WPF from PowerShell, so in this release I’ve included full support for these in a way that will, I hope, simply work so well it will boggle your mind :) All you have to do to tell a control, for instance, to be in the 3rd column of a grid is to just pass Button "Click Me" -"Grid:Column" 2 … it’s THAT simple. In fact, for properties that have unique names, you don’t even have to specify the type, just the name, like -Row 3 to specify the grid row.

Regression and Backwards Compatibility

Of course, the downside of these changes is that some of the syntax has changed a little bit. All scripts and event handlers (ie: click handlers for WPF Buttons) are run from the dll module scope in PowerShell 2 (the global scope in PowerShell 1), which means that they can’t access “script” scope variables from your scripts (which ends up meaning you have to declare a lot of things global that you could leave in script scope before). Just to be clear on the quality of this release: once we have ironed out the minor problems we’re having with PowerShell 1.0 in a way that I’m comfortable with, I expect to push the version number up and release an 1.0 Release Candidate, barring any major issues.

In order to help with the transition, I’ve included a Samples.ps1 script which has 28 sample scripts in it (mostly from the original Tutorial Walk-through, which I will update soon). I’ve updated each of them to work with this release, in both PowerShell 1 and PowerShell 2 (which means they’re almost all written in PowerShell 1 syntax), so you can use them as good examples of how to get things done!

Please use the Discussions Forum and Issue Tracker on the CodePlex site to post any problems you have, and I’ll try to write up a few more posts describing changes and differences in the next couple of weeks.

Reblog this post [with Zemanta]

[new] Updated to PowerBoots 0.1

An introduction to PowerBoots

Please excuse me if I start by just copying the basic ideas of the Shoes Tutorial, but I figured that since PowerBoots is inspired by Shoes, that was as good a place as any to start. PowerBoots (or just “Boots”) is a PowerShell 2.0 module with functions for writing Windows Presentation Framework (WPF) applications in the PowerShell scripting language. You should get the latest version of PowerBoots before continuing, and install it by putting the “PowerBoots” folder in one of your “Modules” folders (list them by typing $Env:PSMODULEPATH in PowerShell v2).

Don’t forget to start PowerShell.exe with the STA parameter (This is no longer required in PowerBoots 0.1).

Did I hear someone ask what is WPF? It was introduced as part of .Net 3.0 (and vastly improved in .Net 3.5), so you can expect to find it preinstalled on computers from Vista on, and of course you can download and install it on XP if it’s not already installed. The only thing you really need to know about WPF for the purposes of this tutorial is that it is the new GUI toolkit for .Net, and that it is container based — you put elements into other elements to control the layout, rather like HTML and Java Swing… you can pick up the rest as we go along.

A simple Boots program


New-BootsWindow -SizeToContent WidthAndHeight -Content (
   Button -Content "Push Me"
)

 

The parenthesis ( and ) are a container, so the button is “in” the Window. You can also pass a ScriptBlock instead, which works basically the same way. Of course, this is a bit uglier than the Shoes syntax, so lets see if we can’t clean it up some. The -Content parameter is positional, so the first non-named argument you pass will be used for that. The same is true for the -Children parameter of panels, and in fact, each of the other similar parameters: Items, Blocks, and Inlines.

We have used a function New-BootsWindow which has an alias Boots. Boots takes all the same parameters as the Window function mentioned previously, but it uses slightly more useful defaults, and has a few other major benefits as well, the first of which is that it automatically “shows” the window, and the second is that it supports an -Async parameter which allows the window to come out in a new thread so that you can continue using PowerShell while the window remains alive and responsive. There is one catch: New-BootsWindow cannot take it’s content on the pipeline (the old function, now renamed “Out-BootsWindow” can take pipeline content, but is a script function, and requires -STA mode) — you have to specify it as a ScriptBlock. So now that we know this, we can rewrite our first example like this:


Boots { Button -Content "Push Me" }
 

Just for the record, the simplest Boots program would just be a simple popup dialog to put some text in a Window, like: Boots { $msg }

We can put controls in a stack


Boots {
   StackPanel {
      Button "A bed of clams"
      Button "A coalition of cheetas"
      Button "A gulp of swallows"
   }
}
 

StackPanels are awesome. So are WrapPanels. Try that code with a WrapPanel instead of a StackPanel and see what the difference is. This brings up another point: those positional parameters we mentioned earlier: Content, Children, Items, Blocks, and Inlines, are also set to accept the value from the pipeline. Not only that, but they are intelligent about whether or not the content model accepts multiple items! So we can actually rewrite that script like this, and get the same results:


Boots { "A bed of clams", "A coalition of cheetas", "A gulp of swallows" | Button | StackPanel }
 

Now we’re really onto something! Read the rest of this entry »

Awhile back I wrote a series of posts about WPF From PowerShell From PowerShell” which were about how you could load XAML in previous PowerShell 2 CTPs to create WPF user interfaces … a few people have mentioned loading XAML in PowerBoots, and a couple of people have posted other samples showing XAML even since I published the most recent release, so I figure it’s time to point out that you really can load that XAML into Boots, and get all the threading and other support.

Just for fun, I’m going to rehash an earlier post about updating windows to show how you can go about this using PowerBoots, and hopefully show that it’s a little easier (and a lot more async). Compare and contrast the code in this article with that one, just for fun.

This works with any version of PowerShell

Unlike the original article, most this code (except where explicitly mentioned) works on either PowerShell v2 with PowerBoots, or PowerShell 1.0 with PoshWPF, a snapin that is part of the PowerBoots module but is also released separately… Also, unlike those previous posts, this does not require you to be running PowerShell.exe with the -STA switch, since the New-BootsWindow cmdlet takes care of threading for us.

Read the rest of this entry »

WPF uses a concept called “Attached Properties” to handle certain things, like when you put controls into a DockPanel. Basically, anything you put inside a DockPanel has a property “Dock” which you can set … but because the property is actually defined by the DockPanel, it doesn’t show up in PowerBoots, so you can’t just say -Dock "Bottom" when you create the child items … at least, not yet.

I’m still thinking about the best way for me to expose this in PowerBoots, because the problem is that attached properties can get attached several ways, and not just on direct children of an element. So I wanted to show you a way that you can do it for now so you can at least use the DockPanel effectively:

Boots {
   DockPanel -LastChildFill $true {
      DockPanel -LastChildFill $true {
         Button "OK" -Padding "2,0,2,0" |
            ForEach-Object { $_.SetValue(
               [System.Windows.Controls.DockPanel]::DockProperty,
               [System.Windows.Controls.Dock]::Right)
               $_
            }
         TextBox -HorizontalAlignment Stretch
      } | ForEach-Object { $_.SetValue(
               [System.Windows.Controls.DockPanel]::DockProperty,
               [System.Windows.Controls.Dock]::Bottom)
               $_
            }
      TextBox -AcceptsReturn $true -minWidth 300 -minHeight 200
   }
}

A better way …

Here’s what I’m thinking about for the next release of PowerBoots (you can take this and use it now, if you like it, but I’m really looking for, uhm … better ideas). Basically, I have written a function: Set-AttachedProperty, which takes an attached property and a value, and passes through the element on the pipeline. You may want to use this in conjunction with the module I published awhile back for creating type accelerators, because it lets you run a line like this:

Add-Accelerator DockPanel System.Windows.Controls.DockPanel

Which will let you substitute [DockPanel] for [System.Windows.Controls.DockPanel] … and of course, you can use it for all the types you want to use attached properties from, and it’s a real lifesaver if you need to use a bunch of them. Of course, in this particular example, we really only need to use a single attached property, so it’s enough to define that property ahead of time:

$DockProperty = [System.Windows.Controls.DockPanel]::DockProperty

Then you can use the Set-AttachedProperty function through an alias sap, and rewrite that huge block above like this:

Boots {
   DockPanel -LastChildFill $true {
      DockPanel -LastChildFill $true {
         Button "OK" -Padding "2,0,2,0" | sap $DockProperty Right
         TextBox -HorizontalAlignment Stretch
      } | sap $DockProperty Bottom
      TextBox -AcceptsReturn $true -minWidth 300 -minHeight 200
   }
}

Pretty slick, right? And it will even print out the list of values in the error message if you invoke it with an invalid value against an enum property like dock: sap $DockProperty "" … The problem I have with it is that you have to predefine your $DockProperty variable, and you can’t just define it against the root class. So I’m trying to find a way to tweak the dynamic property generation to make it so that the pipe into | sap $DockProperty Bottom can just be a parameter to the original element: -Dock Bottom … if I can’t find that, in the worst case scenario, I’ll just add an -AttachedProperties parameter with a hashtable of $DockProperty,“Bottom” or something … what do you think?

In any case, here’s the sap function, for now, and remember to use it as part of the pipeline:


function Set-AttachedProperty {
[CmdletBinding()]
PARAM(
   [Parameter(Position=0,Mandatory=$true)
   [System.Windows.DependencyProperty]
   $Property
,
   [Parameter(Mandatory=$true,ValueFromPipeline=$true)
   $Element
)
DYNAMICPARAM {
   $paramDictionary = new-object System.Management.Automation.RuntimeDefinedParameterDictionary
   $Param1 = new-object System.Management.Automation.RuntimeDefinedParameter
   $Param1.Name = "Value"
   # $Param1.Attributes.Add( (New-ParameterAttribute -Position 1) )
   $Param1.Attributes.Add( (New-Object System.Management.Automation.ParameterAttribute -Property @{ Position = 1 }) )
   $Param1.ParameterType = $Property.PropertyType
           
   $paramDictionary.Add("Value", $Param1)
   
   return $paramDictionary
}
PROCESS {
   $Element.SetValue($Property, $Param1.Value)
   $Element
}
}

New-Alias sap Set-AttachedProperty
 

Announcing the release of PowerBoots 0.1

This release of PowerBoots is the most exciting release software I’ve cranked out in awhile. It finally has almost all of the features that I have thought of so far (we’re still missing proper support for attached properties).

  • You can create pretty much any WPF element, including ones I haven’t thought of adding yet (use Add-BootsFunction to add a new assembly or a single type).
  • You can create graphical user interfaces from PowerShell 1.0 all the way to the latest PowerShell 2.0 CTP.
  • You can create your WPF GUIs -Async in their own threads, or inline in PoshConsole, or as synchronous dialogs that return values when they close.
  • You can capture screenshots of your UIs (eg: generate .jpg charts from Visifire). You can even do so without displaying them!
  • You can take advantage of XAML Data Templates to generate graphical representations of any objects in the PowerShell pipeline.
  • You can add to, or modify your running GUIs from the command line.

You can read the “and much much more” between the lines right?

Read the rest of this entry »

Once I started playing with the new ability, introduced in PowerBoots 0.0.4 to easily add support for new graphical controls to PowerBoots, I found all sorts of fun widgets out there in open-source land. I’ll write about a few of them in the future, but for now I’m just going to stick with Visifire. After playing with a few examples, I finally got around to actually trying to create the graphs I needed at work which were the main source of motivation for trying to do Visifire from PowerShell anyway …

The problem was, half of the need we have for graphs is to throw them up on a web-server … so I needed a way to take the WPF window, and capture the controls and visuals as an image. Basically, render the WPF control to a bitmap image, instead of to the screen. To cut a long story short, I figured it out of course — why else would I be writing this? (get it here).

Out-BootsImage

So the new version of PowerBoots includes the Out-BootsImage function (aliased as BootsImage and “obi”), which basically is designed to take the filename of an image, and a boots visual element, and create a screenshot. It can generate bmp, gif, jpg, png, tiff, and even Microsoft’s new wdp format, or it can output to clipboard.

It’s late, so I’m not going to write any more about this … the bottom line is, if you have been looking for a (free) way to generate graphs and charts to image files in PowerShell, this will work for you: go grab Visifire, check out their gallery for inspiration, and start churning out graphs! Just for fun, here are the samples from the help documentation (except, this is the actual script I ran, including the upload code) with screen-shots …

Important note

When producing images of Visifire charts using this method, it is absolutely critical that you must specify -Animation $false because otherwise you will consistenly produce images of empty charts (since by default Visifire animates all of the bars onto the screen right after the SourceInitialized event that I use to capture the image). Oh, and if you need to remove the Visifire.com watermark, there is a -watermark $false parameter on the Chart element, which turns it off.


$credential = Get-Credential

Chart -Width 200 -Height 150 -Theme Theme3 -Watermark $false -Animation $false (
   DataSeries $(
      1..(Get-Random -min 3 -max 6) | ForEach-Object  {
         DataPoint -YValue (Get-Random 100)
      }
   )
) | Out-BootsImage VisiFire-BootsImage.jpg |ForEach-Object {
   Send-FTP HuddledMasses.org $credential -LocalFile $_ -Remotefile "$imgPath/$($_.Name)"
   [Windows.Clipboard]::SetText( "!http://huddledmasses.org/images/PowerBoots/$($_.Name)!" )
}

StackPanel -Margin "10,5,10,5" $(
   Label "Please enter your name:"
   StackPanel -Orientation Horizontal $(
      TextBox -OutVariable global:textbox -Width 150 -On_KeyDown {
         if($_.Key -eq "Return") {
            Write-Output $textbox[0].Text
            $BootsWindow.Close()
         }
      }
      Button "Ok" -Padding "5,0,5,0" -Margin "2,0,0,0" -On_Click {
         Write-Output $textbox[0].Text
         $BootsWindow.Close()
      }
   )
) | Out-BootsImage BootsImage-Screenshot.jpg | ForEach-Object {
   Send-FTP HuddledMasses.org $credential -LocalFile $_ -Remotefile "$imgPath/$($_.Name)"
   [Windows.Clipboard]::SetText( "!http://huddledmasses.org/images/PowerBoots/$($_.Name)!" )
}
 

This is the fourth release of the PowerBoots module for PowerShell 2 (Download7z). PowerBoots is a framework for creating WPF GUIs from PowerShell, and this latest release brings a couple of bug fixes and two new features.

Now with tab completion

The biggest change in PowerBoots 0.0.4 is that tab-completion for parameters works in the shell.

Behind the scenes what has happened is that I’ve discovered that in the current CTP3 release of PowerShell 2, Dynamic Parameter sets are not handled correctly for aliases, and the Get-Command for aliases of functions doesn’t return the same set of parameters as it does on the function itself. The result is that Tab-Completion for dynamic parameters doesn’t work on aliases (neither the built-in tab completion, nor MoW’s PowerTab). I wrote up a bug against that, but I also found that I can work around it by creating hundreds of functions (all pointed at the same script-block), instead of hundreds of aliases (all pointed at the same function).

PowerBoots produces functions instead aliases

This means the PowerBoots commands show up by default when you run Get-Command. Incidentally, this means that the first time you run Get-Command after you Import-Module PowerBoots you incur a huge penalty (17 seconds on my machine) while Get-Command caches all the dynamic parameter information about the functions. NOTE: because of the DynamicParam bug, I’ve ditched aliases altogether for this particular project and am generating two functions for each element/type in PowerBoots: the full New-Namespace.Type version, and a “Type” alias when possible. Trust me when I say: “it’s worth it” ... with the backing scriptblock, there’s virtually no difference between the two approches in terms of resources (other than the aforementions hit on Get-Command).

Now with more controls

The second big change (and the one which I hope will have the biggest long-term impact) is that you can now import your own WPF control libraries into PowerBoots. This means that you can, for example, go get the open source Visifire charting library, extract their WPFVisifire.Charts library into your PowerShell folder, and use it like so:


Add-BootsContentProperty 'DataPoints', 'Series'
Add-BootsFunction -Assembly "~\Documents\WindowsPowershell\Libraries\WPFVisifire.Charts.dll"

Chart -Width 200 -Height 150 -Theme Theme3 (
  DataSeries $(
      DataPoint -YValue (Get-Random 100)
      DataPoint -YValue (Get-Random 100)
      DataPoint -YValue (Get-Random 100)
      DataPoint -YValue (Get-Random 100)
  )
) | Boots -Title "Sample, Theme 3"
 
Read the rest of this entry »

[new] You should check out the new release of PowerBoots, and the walkthrough PowerBoots Tutorial that I wrote up … this post is getting out of date. :)

If you haven’t seen the Ruby Shoes graphical framework, you should check it out. In fact, go read the tutorial and come back, because the rest of this will make a lot more sense then.

It’s a very slick toolkit, right?

From my previous post introducing PowerBoots

Well, here it is: PowerBoots 0.0.1

I hacked some things together in binary form, and Jeffrey Snover did some pure magic in a script, and after playing with various different mixes of it, I’m going to release the pure-script, CTP3-only, PowerBoots module now, and I’ll follow up with the backwards-compatible Out-WPF that gives you external threading later on.

I think you’ll find this is pretty slick already

Unpack the “PowerBoots” folder into one of your Module folders, and then just run imo PowerBoots and you’re off to the races. Imo is not short for immolate, nor for “in my opinion” ... it’s the alias for the newly renamed Import-Module cmdlet.

Once you’ve got that set up, check out the Demo-PowerBoots.ps1 script. Don’t just run it — open it in an editor and check it out, then run a few of the individual sections, and play with them to get a feel for how this works.

I’ll have more very soon, but for now, let me tantalize you with this little demo:


#Requires -version 2.0
#And requires -STA
Import-Module PowerBoots # http://huddledmasses.org/downloads/PowerBoots.7z
Import-Module HttpRest   # Version 1.0.1 http://www.poshcode.org/787

$url = "http://www.gutenberg.org/catalog/world/readfile"
function Update-Page($pg,$bk=53){
   @($textBox)[0].Text = Get-WebPageContent $url -with @{fk_files=$bk; pageno=$pg} //pre
   @($pageLabel)[0].Content = "Page: $pg"
}

#################
## The actual GUI code:
$window = Window -Title "Shakespeare's Richard III" -SizeToContent "WidthAndHeight" -Content (
            StackPanel -Children $(
              GridPanel -Children $(
                Image -Source 'http://huddledmasses.org/wordpress/wp-content/uploads/2009/01/eagle-crop.jpg' -height 250
                Label -Content "Richard III" -FontSize 52 -HorizontalAlignment Right -VerticalAlignment Bottom
              )
              StackPanel -Orientation Horizontal -Children $(
                Button -Content "Previous Page" -On_Click {Update-Page (--$page) $book}
                Label  -Content "Page $pg" -OutVariable PageLabel
                Button -Content "Next Page"     -On_Click {Update-Page (++$page) $book}
              )
              TextBox -OutVariable TextBox
            )
          )

$page=20; $book=53
Update-Page $page $book
$window.ShowDialog()

I’m almost ready to release a version of Out-WPF which will work on both my PoshConsole host (embedding in the host when appropriate) and on PowerShell.exe, both in CTP3 and in v1 … but since Jeffrey outed my little video demo, I figured I might as well share it here. Read the rest of this entry »

If you haven’t seen the Ruby Shoes graphical framework, you should check it out. In fact, go read the tutorial and come back, because the rest of this will make a lot more sense then.

It’s a very slick toolkit, right? Not only that, but it works on Windows, Linux, and Mac OS X … unlike what I’m about to show you, which works only where PowerShell works …

So, I’m curious if anyone would like something like that for PowerShell … and more to the point, how many people would be interested in it, and whether anyone would be willing to help write it (because exposing all of the properties of the various controls is going to require a lot of repetitive coding).

What would it look like in PowerShell?

The simplest PowerBoots app

The simplest PowerBoots app


# These lines are the same (#2 uses aliases)
New-Button "Push Me" | Out-WPF
button "Push Me" | Wpf
A few more buttons, in a stack

A few more buttons, in a stack


# Again, these lines are the same (#2 uses aliases)
"A bed of clams", "A coalition of cheetahs", "A gulp of swallows" | New-Button | New-Stack | Out-Wpf
"A bed of clams", "A coalition of cheetahs", "A gulp of swallows" | Button | Stack | Wpf

As a disclaimer, I copied the examples here from the Shoes tutorial I mentioned earlier, which is why they’re slightly kooky (Why The Lucky Stiff is a strange guy), and why I suggested you go read it before you read this. Of course, although these demos do work —and it’s all skinable and themeable— this is practically all that works in my demo, so don’t go thinking I’ve got a whole Shoes implementation for PowerShell.

A few options

A few options


"A bed of clams", "A coalition of cheetahs", "A gulp of swallows" | Button -margin 2 | Stack -margin 8 -background red | Wpf

I’m just trying to gauge the interest level — so if you’re interested, please comment below and let me know that you want it, what sorts of things you want it for (if you can think of any off the top of your head), and/or how involved you’d like to be. I’d love for someone to say: “Wow, that’s a great idea, I’m going to go finish it”, but anything short of that, right down to “I’d give you $5 to write it and give it away” is acceptable ;)

One final note: the Out-Wpf cmdlet that you see here does work in v1 and v2 and can even do this (click for the full picture):

Out-WPF without PoshConsole

Out-WPF without PoshConsole

I’ll release that later this week…

[new] PowerBoots Release

I’ve released a full script-based version of this. While it does everything you see above and more, it does not work in PowerShell 1. You can get an idea of how to use it by following the PowerBoots tutorial, and you can download PowerBoots, but for now it requires v2 CTP3. Let me hear from you if v1 support is important to ya.

Search My Content