Categories

16065

A PowerShell clock

I don’t do much with Windows forms as the vast majority of what I do is at the admin end of the PowerShell spectrum. Every now and then I like to play. A recent post on the forum asking about displaying a clock from PowerShell looked like a good excuse.

I ended up using Windows Presentation Foundation - http://msdn.microsoft.com/en-us/library/ms754130.aspx

save this as clock.xaml

<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        WindowStyle='None' AllowsTransparency='True'
        Topmost='True' Background="Transparent"  ShowInTaskbar='False'
        SizeToContent='WidthAndHeight' WindowStartupLocation='CenterOwner' >
   <Window.Resources>
      <system:String x:Key="Time">12:34.56</system:String>
   </Window.Resources>


   <Grid Height="2.2in">
      <Grid.ColumnDefinitions>
         <ColumnDefinition/>
      </Grid.ColumnDefinitions>
      <Label Name="Clock" Grid.Column="2" Content="{DynamicResource Time}" FontFamily="Impact, Arial" FontWeight="800" FontSize="1in" >
         <Label.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"/>
            </LinearGradientBrush>
         </Label.Foreground>
      </Label>
   </Grid>
</Window>

save this as clock.ps1

#Import the WPF assemblies            
 Add-Type -Assembly PresentationFramework            
 Add-Type -Assembly PresentationCore            
             
$clock = [Windows.Markup.XamlReader]::Load(             
         (New-Object System.Xml.XmlNodeReader (            
             [Xml](Get-Content "C:\scripts\wpf\clock.xaml") ) ) )            
             
## Create a script block which will update the UI            
 $counter = 0;            
 $updateBlock = {            
    # Update the clock            
    $clock.Resources["Time"] = [DateTime]::Now.ToString("T")            
 }            
             
## Hook up some event handlers             
$clock.Add_SourceInitialized( {            
    ## Before the window's even displayed ...            
    ## We'll create a timer            
    $timer = new-object System.Windows.Threading.DispatcherTimer            
    ## Which will fire 4 times every second            
    $timer.Interval = [TimeSpan]"0:0:0.25"            
    ## And will invoke the $updateBlock            
    $timer.Add_Tick( $updateBlock )            
    ## Now start the timer running            
    $timer.Start()            
    if( $timer.IsEnabled ) {            
       Write-Host "Clock is running. Don't forget: RIGHT-CLICK to close it."            
    } else {            
       $clock.Close()            
       Write-Error "Timer didn't start"            
    }            
 } )            
             
$clock.Add_MouseLeftButtonDown( {             
   $_.Handled = $true            
    $clock.DragMove() # WPF Magic!            
 } )            
 $clock.Add_MouseRightButtonDown( {             
   $_.Handled = $true            
    $timer.Stop()  # we'd like to stop that timer now, thanks.            
    $clock.Close() # and close the windows            
 } )            
             
## Lets go ahead and invoke that update block             
&$updateBlock            
 ## And then show the window            
 $clock.ShowDialog()


 



A rainbow clock is displayed that updates every second. Right click it to close. Change the size using the FontSize property.



Run from ISE or PowerShell started in STA mode.



This has been adapted from original posts by Oisin and Jaykul



http://nivot.org/nivot2/post/2008/05/23/BackgroundTimerPowerShellWPFWidget.aspx



http://huddledmasses.org/wpf-from-powershell-updating-windows/