Register HERE

The topic: Extending PowerShell to the GUI with ShowUI. ShowUI is a PowerShell module to help build WPF user interfaces in script. ShowUI makes the complicated world of WPF easy to use in PowerShell.

I will be demoing How To

  • Build a standalone PowerShell ShowUI WPF application
  • Run this app in the background
  • Get data asynchronously
  • Use variable splatting to enable the app as a custom control
  • Use the same app standalone, in the background and embedded in another ShowUI WPF app
  • The common controls we currently deliver with ShowUI out of the box

It’s going to be fun, informational talk. Looking forward to it.

Share

{ 0 comments }

This is good, check it out HERE.

ThoughtWorks is "A social and commercial community whose purpose is to revolutionize software creation and delivery while advocating for positive social change in the world."

I follow and respect several at ThoughtWorks, for example Martin Fowler and Neal Ford.

The Tech Radar places PowerShell in the “Trial” quadrant but I suspect that to quickly move to the “Adopt” quadrant after the Microsoft BUILD Conference when the new features of Windows 8 is announced.

Exciting times.

Share

{ 0 comments }

Sean Kearny wrote Extending PowerShell to the GUI with Sapien Tools up on Hey, Scripting Guy! Blog. SAPIEN has a product, PrimalForms, which lets you create WinForm applications using PowerShell. One of the advantages using this approach; WinForms is ready out of the box on an end users Windows machine.

In this post I’ll use ShowUI and port Sean’s example. The challenge, ShowUI is a PowerShell Module that needs to be xCopy deployed to the users machine so I can create these WPF GUI applications.

ShowUI

ShowUI is a PowerShell module to help build WPF user interfaces in script. ShowUI makes the complicated world of WPF easy to use in PowerShell.

Sean steps through creating a simple GUI for capturing a user’s first and last name so it can be used with PowerGUI’s Get-QADUser cmdlet. First up, is a simple form with an ‘UNLOCK Account’ button.

Button "Unlock Account" -Show -Margin 10 -On_Loaded {
    $Window.Title = "Our Help Desk"
}

image

Now, Capture the User Information

I’ll wrap the ShowUI code in a function Get-UserInfo. I like this practice because it makes the GUI widget reusable. In an upcoming post I’ll drill down on how to create custom controls. For now I will reproduce Sean’s user info screen.

I use a WPF Grid which lets me lay out controls in Rows and Columns. I use 3 rows, one row for the labels, one for the text boxes and the last for the button. Every control in ShowUI supports a Row and Column parameter, so they can all be laid out this way.

I write fewer lines of code using a WPF grid container. For example, when I resize the window all the controls resize automatically. Give it a try.

Next up, I show the magic to returning the data entered on the form as PowerShell Hashtable.

function Get-UserInfo {
    Grid -Rows 3 -Columns 2 -Show -On_Loaded {
        $Window.Title = "Our Help Desk"
    } {            

        Label "First Name" -Row 0 -Column 0 -FontWeight Bold
        Label "Last Name" -Row 0 -Column 1 -FontWeight Bold              

        TextBox -Row 1 -Column 0 -Margin 5 -Name FirstName
        TextBox -Row 1 -Column 1 -Margin 5 -Name LastName            

        Button "Unlock Account" -On_Click {
            $Window | Set-UIValue -passThru | Close-Control
        } -IsDefault -Margin 5 -Row 2 -Column 0 -ColumnSpan 2
    }
}            

Get-UserInfo            

# Returns and Prints the hashtable
@"
Name      Value
----      -----
FirstName Mister
LastName  Trouble
"@            

image

Pressing the button returns a Hash Table

Here is I how I set this up to work. I named the TextBox controls FirstName and LastName. Then in the Button –On_Click event, I pipe the $Window automatic variable to the ShowUI Set-UIValue cmdlet. Set-UIValue takes the content of the TextBox and copies it to the Tag properties. Then, when the form is closed, via Close-Control, the Tag properties are scanned and the name and tag of that control are added to the  hash table as a key value pair.

Variable Splatting

Hashtables (aka associative arrays) are great data structures. Plus, in PowerShell you can use them to do variable splatting.

This is a term taken from the Ruby scripting language and affects how argument variables are passed to commands. – Bruce Payette Windows PowerShell In Action 2nd Edition

To do this is, when referencing the variable that you want to pass to the command, you use @ instead of $ as the prefix to the variable.

Conclusion

So, I can squirrel away my Get-UserInfo function and reuse it. Then, calling the Get-QADUser cmdlet becomes even simpler.

$userInfo = Get-UserInfo
Get-QADUser @userInfo

This approach has another benefit. I can add another TextBox to my GUI, name it the same name as a parameter on Get-QADUser and it will seamlessly work.

These are some of the high order abstractions I and my fellow ShowUI authors, James Brundage and Joel Bennett, are building into ShowUI.

Give it a try and drop us line on CodePlex or our blogs if you have questions or suggestions.

Share

{ 3 comments }

Denniver Reining posted GUI Creation with PowerShell: The Basics using PowerShell and WinForms to create an application where you type a user id, click go and it executes a Net User under the covers.

Highlights

I ported his code to ShowUI and focused on the elements he did:

  • Control resizing (Using the Grid)
  • Adding controls to a Window
  • Attaching events (On_Click parameter for the button)
  • Changing control fonts (FontFamily parameter for the text box)

Using WinForms and PowerShell are a great approach to building GUIs. One advantage WinForms has over ShowUI is it is available on any machine you deliver your PowerShell script to.

ShowUI leverages WPF and while it requires investment and a module, the value per line of code is compelling.

image

PowerShell Code

Import-Module ShowUI            

$windowAttributes = @{
    Title = "ShowUI Form"
    WindowStartupLocation = "CenterScreen"
    SizeToContent = "WidthAndHeight"
}            

New-Window @windowAttributes -Show {            

    Grid -Columns 75*, 75 -Rows 40, 10* {
        TextBox -Name UserId -Row 0 -Column 0 -Margin 5 -Text finked            

        Button _Go -Row 0 -Column 1 -Margin 5 -On_Click {            

            foreach( $record in (net user $UserId.Text) ) {
                $result.appendText("$record `r`n")
            }
        }            

        TextBox -Name Result `
            -Row 1 -Column 0 -ColumnSpan 2 `
            -Margin 5 -IsReadOnly `
            -FontFamily "Courier New"
    }
}

Related

Share

{ 2 comments }

Learn how

Wednesday July 20th I’ll be joining fellow ShowUI authors James Brundage and Joel “Jaykul” Bennett on the PowerScripting Podcast.

ShowUI is a PowerShell module to help build WPF user interfaces in script. ShowUI makes the complicated world of WPF easy to use in PowerShell. You can use ShowUI to write simple WPF gadgets, quick front ends for your scripts, components, and full applications.

Related

 

Share

{ 1 comment }

DARPA is soliciting innovative research proposals in the area of social media in strategic communication.

The conditions under which our Armed Forces conduct operations are rapidly changing with the spread of blogs, social networking sites, and media sharing technology (such as YouTube), and further accelerated by the proliferation of mobile technology.

In a millisecond, millions of people of people all over the world can know everything about everything and everyone. – Jeffrey Gitomer

Changes to the nature of conflict resulting from the use of social media are likely to be as profound as those resulting from previous communications revolutions. The effective use of social media has the potential to help the Armed Forces better understand the environment in which it operates and to allow more agile use of information in support of operations.

Social Media in Strategic Communication DARPA document.

Share

{ 0 comments }

Node.js V0.5.1 released a Windows binary. Download the Windows Build.

PowerShell

Here is an example of a web server written in Node which responds with "Hello World" for every request.

This is a single PowerShell script that saves the JavaScript to a file, launches node and then uses the .NET framework Net.WebClient to make a request.

$ip = "127.0.0.1"
$port = 337
$url = "http://{0}:{1}/" -f $ip, $port            

@"
var http = require('http');
http.createServer(function (req, res) {
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end('Hello World\n');
}).listen($port, "$ip");

console.log('Server running at ${url}');
"@ | Set-Content -Encoding ascii c:\example.js            

Start-Process powershell -ArgumentList "C:\node\node.exe c:\example.js"            

sleep 1
(New-Object net.webclient).DownloadString($url)

Result

image

Share

{ 2 comments }

A question I often get about PowerShell from ex-UNIX developers is whether or not PowerShell can “tail” files. Unfortunately, there is no direct analogy to the tail command in PowerShell. It’s typically used to watch the contents of a log file live as it is added to, and that is certainly something that PowerShell can do.

This question comes from a developer who is using NLog to log messages from his app involving Reactive Framework code.

Get-Content –Wait C:\Test.txt

Get-Content is a PowerShell cmdlet (aliased to type (for DOS people) and cat (for Unix people)). It gets the content of the item at the location specified by the path, such as the text in a file. imageIt reads the content one line at a time and returns a collection of objects, each of which represents a line of content.

The –Wait parameter waits for content to be appended to the file. If content is appended, it returns the appended content.

Out-GridView

You can pipe the results of PowerShell to a grid view window where the output is displayed in an interactive table. Out-GridView is available out of the box.

Features of Out-GridView

  • Hide, Show, and Reorder Columns
  • Sort
  • Quick Filter
  • Criteria Filter
  • Copy and paste

How To

Get-Content –Wait c:\test.txt | Out-GridView. As the data is updated from the background task (see code below), another line is added to the table. You can even do a quick filter and as the lines are appended to the file, Out-GridView adds them applies the filter to the new information.

image

Try It Out

del C:\test.txt            

Start-Job -ScriptBlock {
    "Time,Message" | Add-Content c:\test.txt
    while($true) {
        "Testa", "Testb","Testc","Testd" | Get-Random | % {
            "{0},{1}" -f (Get-Date).ToString(), $_
        } | Add-Content c:\test.txt
        Start-Sleep -Milliseconds 1500
    }
}            

sleep 2
Get-Content c:\test.txt -wait |  ConvertFrom-Csv | Out-GridView
Share

{ 2 comments }

Interactive Extensions (Ix) introduces a set of additional LINQ to Objects query operators based on the work done in the Reactive Extensions (Rx).

Bart clearly explains what Ix is and why they’ve built this library, what it’s for, and when to go interactive. This is a deep conversational piece with plenty of whiteboarding during which we also talk about the current status of IQbservable.

Share

{ 0 comments }

image

I posted PowerShell Clock with ShowUI. Ravi, another PowerShell MVP, tried the sample using the AsJob parameter. The AsJob will run the PowerShell WPF GUI in the background. Unfortunately, the FontSize and other parameters would not set correctly and the clocked was not readable.

After emailing James Brundage, a fellow ShowUI author , he blogged Six Steps for Writing ShowUI Controls and a video tutorial based on this clock example.

Definitely check it out, he kicks it up a notch with data context’s, PowerShell DataSources. splatting, adding event handlers and more.

Here is my updated clock code

Run it with either –Show or –AsJob

HippyDippy-Clock -Show
HippyDippy-Clock -AsJob
function HippyDippy-Clock {
    param (
        [string]$Name,
        [Int]$Row,
        [Int]$Column,
        [Int]$RowSpan,
        [Int]$ColumnSpan,
        [Int]$Width,
        [Int]$Height,
        [Double]$Top,
        [Double]$Left,
        [Windows.Controls.Dock]$Dock,
        [Switch]$Show,
        [Switch]$AsJob
    )            

    begin {ipmo showui}
    process {
        if (-not $psBoundParameters.Background) {
            $psBoundParameters.Background = 'Transparent'
        }                        

        $uiParameters = @{} + $psBoundParameters            

        Border @uiParameters -On_Loaded {
            $this.Child = Grid -Columns 150, 300* {
                Image -Source "http://weaselzippers.us/wp-content/uploads/2011/05/hippie.jpg" -Column 0
                Label -Name Target -FontSize 90 -Column 1 `
                    -FontFamily "Impact, Arial" -FontWeight 800 -Foreground (
                    LinearGradientBrush $(
                        GradientStop -Color Red    -Offset 1
                        GradientStop -Color Orange -Offset 0.85
                        GradientStop -Color Yellow -Offset 0.7
                        GradientStop -Color Green  -Offset 0.55
                        GradientStop -Color Blue   -Offset 0.4
                        GradientStop -Color Indigo -Offset 0.2
                        GradientStop -Color Violet -Offset 0
                    )
                )
            }            

            $this.DataContext = Get-PowerShellDataSource -On_OutputChanged {
                $output = Get-PowerShellOutput -Last -OutputOnly
                $Target.Content = $output
            } -Script {
                while ($true) {
                    (Get-Date).ToString('T'); Start-Sleep -Seconds 1
    }
            }                

        } -On_Initialized {
            $window.SizeToContent         = 'WidthAndHeight'
            $window.WindowStyle           = 'None'
            $window.Background            = 'Transparent'
            $window.AllowsTransparency    = $true
            $window.WindowStartupLocation = 'CenterScreen'            

            Add-EventHandler -EventName "On_Closing" -Handler {
                if ($this.Content.DataContext.Command.Stop) {
                        $this.Content.DataContext.Command.Stop()
                    }
                } -Object $window                                    

                # When the right mouse button is down, close the control            
                Add-EventHandler -EventName "On_PreviewMouseRightButtonDown" -Handler {
                    $_.Handled = $true
                    Close-Control
                } -Object $window            

                Add-EventHandler -EventName "On_PreviewMouseLeftButtonDown" -Handler {
                    $_.Handled = $true
                    $this.DragMove()
                } -Object $window
        }
    }
}
Share

{ 1 comment }