WPF & PowerShell – Part 6 (Running Functions in the Background)

PowerShell Team

For the next part in the series, I’ve introduced another update to the Show-Control function you first met in Part 4.  In this update, I’ve added the ability to run the control you’ve created in a background runspace as a switch.

In order to do this, Show-Control employs a neat little trick.  It actually creates a background runspace, uses Get-Command to find out its own definition, and packs itself into the runspace it just created.  Then it removes the switch parameter that told it to run in the background, but adds every other argument.  It also makes sure to recreate the event handlers that were passed as an argument, since the script block will be running in a different runspace.  The changes also fire some powershell events and create a variable in the background runspace that stores the parent host, but we’ll get to why those two are there tomorrow.

Just having -backgroundRunspace makes taking the video player and turning it into a more complete control a little simpler to do.  You can use =backgroundRunspace on any of the existing examples that use XAML (controls will not cross runspaces nicely), but just having it around makes having a lightweight video player applet really easy.  Here it is.  Our video player is ~40 lines, has play, pause, and stop buttons, and a slider that will let us control the position within the clip.

@”
<StackPanel xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation’>
    <Label FontSize=’14’>PowerShell Video Player – Drag a file here to play it</Label>
    <MediaElement Name=”MediaPlayer” Height=”240″ Width=”320″ LoadedBehavior=”Manual” />    
    <Slider Name=”Position” Minimum=”0″ Maximum=”100″ />
    <StackPanel Orientation=”Horizontal”>
        <Button Name=”PlayButton”>Play</Button>
        <Button Name=”PauseButton”>Pause</Button>
        <Button Name=”StopButton”>Stop</Button>
    </StackPanel>
</StackPanel>
“@ | Show-Control -windowProperties @{“AllowDrop”=$true} -backgroundRunspace -event @{
    “Window.Activated” = {
       $script:mediaPlayer = $window.Content.FindName(“MediaPlayer”)                 
    }
    “Window.Drop”={        
       $mediaPlayer.Source = New-Object System.URI ($_.Data.GetFileDropList() | select -first 1)
       $mediaPlayer.Play()
    }
    “Window.Closed”= {
       $mediaPlayer.Stop()
    }
    “StopButton.Click”={
       $mediaPlayer.Stop()
    }
    “PauseButton.Click”={
       $mediaPlayer.Pause()
    }
    “PlayButton.Click”={
       $mediaPlayer.Play()   
    }
    “Position.ValueChanged”={
       $positionControl = $window.Content.FindName(“Position”)
       if ($mediaPlayer.NaturalDuration.HasTimespan) {
          $percentPerSecond = $mediaPlayer.NaturalDuration.Timespan.TotalSeconds / 100
          $position = $positionControl.Value
          $mediaPlayer.Position = New-Timespan -second ($position * $percentPerSecond)
          $mediaPlayer.Play()
       }
    }
}

While a video player is a prime example of a type of application that you might want to run in the background, it’s only a one way street.  On our final day of the series we’ll show you how to use our updated Show-Control to make controls in the background stream data and talk to the main runspace.

Hope this Helps,

James Brundage [MSFT]

Show-Control.ps1

0 comments

Discussion is closed.

Feedback usabilla icon