Write a GUI in Powershell – Part 7

7. Finish every else in Powershell. This script will run the timer. Once the time is reached, it will run the command.

# (C) Chao Liu
#===========================================================================
# Add CSharp Class to PowerShell
#===========================================================================

$path=$PSScriptRoot
$code=Get-Content -Raw -Path (Join-Path $path "PowerManagerNS.cs")
Add-Type -TypeDefinition $code

$csharp1=Get-Content (Join-Path $path "DynamicViewModel.cs") -Raw
#$csharp1=Get-Content "d:\Programming\XAML For PS\XAML For PS\DynamicDictViewModel.cs" -Raw
Add-Type -TypeDefinition $csharp1

#Add-Type -AssemblyName PresentationFramework
$csharp2=Get-Content (Join-Path $path "ConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp2 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

$csharp3=Get-Content (Join-Path $path "MultiValueConverterWrap.cs") -Raw
Add-Type -TypeDefinition $csharp3 -ReferencedAssemblies @("PresentationFramework";"WindowsBase")

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$xaml = Get-Content -Raw -Path (Join-Path $path "autoshutdown.xaml")

#Read XAML
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Some possible causes for this problem include: .NET Framework is missing PowerShell must be launched with PowerShell -sta, invalid XAML code was encountered."; exit}

$manager = New-Object System.Xml.XmlNamespaceManager $xaml.NameTable;
$manager.AddNamespace("xaml", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
$manager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
$xaml.SelectNodes("//*[@x:Name]", $manager ) | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}
#$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name)}

#===========================================================================
# Create Data Module
#===========================================================================
$now=Get-Date
$viewModel = New-Object DynamicViewModel @{
Interval=1;
TotalTime=New-TimeSpan $now $now.AddHours(1);
EndTime=$now.AddHours(1);
StartTime=$now;
IdleTime=5;
DefaultIdleTime=0;
Running=New-Object TimeSpan;
Stopped=$true;
TypeKey="CountDown";
ExtraMsg="";
Display={("`n{0,-20}{1}" -f "Name","Value"); ("{0,-20}{1}" -f "----------","---------"); $viewModel.Keys |
%{"{0,-20}{1}" -f $_,(&{if(([String]$viewModel[$_]).length -ge 60) {([String]$viewModel[$_]).Substring(0,57)+"..."} else {$viewModel[$_]}})} | Sort }
}

$window.DataContext = $viewModel

#===========================================================================
$c= New-Object ConverterWrap
$c.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
if ($parameter -eq $value){
$true
}
else {
$false
}
}
$c.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
if ($value) {
$parameter
} else {
[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="CountDown"
$b.UpdateSourceTrigger="PropertyChanged"
$rbCountDown.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="EndTime"
$b.UpdateSourceTrigger="PropertyChanged"
$rbEndTime.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="IdleTime"
$b.UpdateSourceTrigger="PropertyChanged"
$rbIdleTime.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TypeKey"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="KeepAwake"
$b.UpdateSourceTrigger="PropertyChanged"
$rbKeepAwake.SetBinding([System.Windows.Controls.RadioButton]::IsCheckedProperty, $b) | out-null

#===========================================================================
for ($i=0; $i -lt 24; $i++) {
$cbHours.Items.Add($i) | Out-Null
}
for ($i=0; $i -lt 60; $i++) {
$cbMinutes.Items.Add($i) | Out-Null
}
for ($i=0; $i -lt 60; $i++) {
$cbSeconds.Items.Add($i) | Out-Null
}

$c= New-Object ConverterWrap
#$c.debugLevel=1
$c.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
#Write-Host "c.ConvertBackPS: " $value
if ($parameter -eq "Hours"){
$value.Hours
}
elseif ($parameter -eq "Minutes"){
$value.Minutes
}
elseif ($parameter -eq "Seconds"){
$value.Seconds
}
else {
[System.Windows.DependencyProperty]::UnsetValue
}
}
$c.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
try{
if ($parameter -eq "Hours"){
New-TimeSpan -Hours $value -Minutes $viewModel.TotalTime.Minutes -Seconds $viewModel.TotalTime.Seconds
}
elseif ($parameter -eq "Minutes"){
New-TimeSpan -Hours $viewModel.TotalTime.Hours -Minutes $value -Seconds $viewModel.TotalTime.Seconds
}
elseif ($parameter -eq "Seconds"){
New-TimeSpan -Hours $viewModel.TotalTime.Hours -Minutes $viewModel.TotalTime.Minutes -Seconds $value
}
else {
[System.Windows.DependencyProperty]::UnsetValue
}

}
catch {
[System.Windows.DependencyProperty]::UnsetValue
#[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Hours"
$b.UpdateSourceTrigger="LostFocus"
$cbHours.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Minutes"
$b.UpdateSourceTrigger="LostFocus"
$cbMinutes.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

$b=New-Object System.Windows.Data.Binding "TotalTime"
$b.Mode="TwoWay"
$b.Converter=$c
$b.ConverterParameter="Seconds"
$b.UpdateSourceTrigger="LostFocus"
$cbSeconds.SetBinding([System.Windows.Controls.ComboBox]::TextProperty, $b) | out-null

#===========================================================================
$c1= New-Object ConverterWrap
#$c1.debugLevel=1
$c1.ConvertPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
"{0:MM/dd/yyyy hh:mm:ss tt}" -f $value
#([Datetime]$value).ToString("MM/dd/yyyy hh:mm:ss tt")
#$value
}
$c1.ConvertBackPS={
param($value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
Write-Host "c1.ConvertBackPS: " $value
try{
[Datetime]$value
}
catch {
[System.Windows.DependencyProperty]::UnsetValue
#[System.Windows.Data.Binding]::DoNothing
}
}

$b=New-Object System.Windows.Data.Binding "EndTime"
$b.Mode="TwoWay"
$b.Converter=$c1
#$b.StringFormat="{0:MM/dd/yyyy hh:mm:ss tt}"
#$b.UpdateSourceTrigger="PropertyChanged"
$tbEndTime.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $b) | out-null

#===========================================================================
$tick={
#Write-Host $args[0]
#Write-Host $args[1]

$now=Get-Date
switch ($viewModel.TypeKey) {
"CountDown" {
$viewModel.Running -= $timer.Interval
}
"EndTime" {
$viewModel.Running = $viewModel.EndTime - $now
}
"IdleTime" {
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$pbStatus.Value = [int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining
$viewModel.Running -= $timer.Interval
#            Write-Host ([int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining -
#                $viewModel.Running.Totalseconds)
if ((([int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining -
$viewModel.Running.Totalseconds) -gt 30) -and
($viewModel.spinfo.TimeRemaining -eq $viewModel.DefaultIdleTime)){
$viewModel.Running = [timespan]::FromMinutes([int]$viewModel.IdleTime)
}
}
"KeepAwake" {
$viewModel.Running = $now - $viewModel.StartTime
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$tbStatus.Text = "Keep Awake. Idle Time: $($viewModel.spinfo.TimeRemaining)"
[PowerManagerNS.PowerManager]::SetThreadExecutionState([PowerManagerNS.PowerManager]::ES_SYSTEM_REQUIRED)
}
}
if ($viewModel.Running.TotalSeconds -gt 0 -and  $viewModel.Running.TotalSeconds -lt $viewModel.Interval*4){
[console]::beep(500,300)
}
if (($viewModel.Running.TotalSeconds -le 0) -and ($viewModel.TypeKey -ne "KeepAwake")){
$timer.Stop();
$viewModel.stopped=$true
$btStart.Content="Start"
[console]::beep(900,900)
TimeReached
}
#UpdateStatus -now $now
}

#===========================================================================
$mc=New-Object MultiValueConverterWrap
$mc.ConvertPS={
param([Object[]]$value, [Type]$targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
$return = $value[0] + " - " + (&{ if($value[3]){"Stopped"} else {"Running"}}) + "`n"
switch ($value[0]) {
"CountDown" {
$end=$now + $viewModel.Running
$text = "Now: $now `nTotal " + ("{0:hh\:mm\:ss}" -f $viewModel.Running) + " to $end"
}

"EndTime" {
$s=[Int]$viewModel.Running.TotalSeconds
$text= "Now: $now `nTotal " + ("{0:hh\:mm\:ss}" -f $viewModel.Running) + " to $($viewModel.EndTime)"
}

"IdleTime" {
$ts =  [timespan]::fromseconds($viewModel.spinfo.TimeRemaining)
$end=$now + $ts
$text = "Idle: "+ ("{0:hh\:mm\:ss}" -f $ts) +"`n" +
"Remain: " + "{0:hh\:mm\:ss}" -f $viewModel.Running
}

"KeepAwake" {
$ts =  [timespan]::fromseconds($viewModel.spinfo.TimeRemaining)
$text = "Idle: "+ ("{0:hh\:mm\:ss}" -f $ts) +"`n" +
"Pass: " + "{0:hh\:mm\:ss}" -f $viewModel.Running
}
}
if ($value[3]) {
$tbStatus.Background = [System.Windows.Media.Brushes]::Transparent

} else {
if (($viewModel.Running.TotalSeconds -lt 60) -and ($viewModel.TypeKey -ne "KeepAwake")){
$tbStatus.Background = [System.Windows.Media.Brushes]::Red
}
}
$return + $text + "`n" + $value[5]

}
$mc.ConvertBackPS={
param($value, $targetType, [Object]$parameter, [System.Globalization.CultureInfo]$culture)
$null
}
$mb = New-Object System.Windows.Data.MultiBinding;
$mb.Converter = $mc;
$mb.Mode = "OneWay"

$b1=New-Object System.Windows.Data.Binding "TypeKey"
$b2=New-Object System.Windows.Data.Binding "TotalTime"
$b3=New-Object System.Windows.Data.Binding "EndTime"
$b4=New-Object System.Windows.Data.Binding "Stopped"
$b5=New-Object System.Windows.Data.Binding "Running"
$b6=New-Object System.Windows.Data.Binding "ExtraMsg"
$mb.Bindings.Add($b1);
$mb.Bindings.Add($b2);
$mb.Bindings.Add($b3);
$mb.Bindings.Add($b4);
$mb.Bindings.Add($b5);
$mb.Bindings.Add($b6);
$tbStatus.SetBinding([System.Windows.Controls.TextBox]::TextProperty, $mb) | out-null

#===========================================================================

$cbHours.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})
$cbMinutes.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})
$cbSeconds.add_GotFocus({
#$rbCountDown.IsChecked = $true
$viewModel.TypeKey="CountDown"
})

$tbEndTime.add_GotFocus({
#$rbEndTime.IsChecked = $true
$viewModel.TypeKey="EndTime"
})

$cbIdleTime.add_GotFocus({
#$rbIdleTime.IsChecked = $true
$viewModel.TypeKey="IdleTime"
})

#Timer Event
$btStart.Add_Click({
#Create Timer object
$now = Get-Date
if (-not $timer) {
#System.Windows.Forms.Timer
$Global:timer = new-object  System.Windows.Threading.DispatcherTimer
$timer.Interval = [TimeSpan]::fromseconds($viewModel.Interval) #($cbInterval.Text)
$timer.Add_Tick($tick)
}

if ($viewModel.Stopped){

switch ($viewModel.TypeKey) {
"CountDown" {
$viewModel.Running = $viewModel.TotalTime
#$pbStatus.Value = $viewModel.Running.TotalSeconds
}

"EndTime" {
$viewModel.Running = $viewModel.EndTime - $now
#$pbStatus.Value = $viewModel.Running.TotalSeconds
}

"IdleTime" {
$viewModel.StartTime = $now
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
$viewModel.DefaultIdleTime = $viewModel.spinfo.TimeRemaining
$viewModel.Running = [timespan]::FromMinutes([int]$viewModel.IdleTime)
#$pbStatus.Value = [int]$viewModel.IdleTime*60 - $viewModel.DefaultIdleTime + $viewModel.spinfo.TimeRemaining
#$tbStatus.Text = "Idle: $ts Now: $now to $end"
}

"KeepAwake" {
$viewModel.StartTime = $now
$viewModel.spinfo = [PowerManagerNS.PowerManager]::GetPowerInformation()
#$tbStatus.Text = "Keep Awake. Idle Time: $($viewModel.spinfo.TimeRemaining)"
}
}
$timer.Interval = [TimeSpan]::fromseconds($viewModel.Interval)

$pbStatus.Minimum = 0
$pbStatus.Maximum = $viewModel.Running.TotalSeconds
$viewModel.Stopped = $false;
#        if ($viewModel.Running -lt [TimeSpan]::FromSeconds(60)){
#            $tbStatus.Background = [System.Windows.Media.Brushes]::Red
#        } else {
#            $tbStatus.Background = [System.Windows.Media.Brushes]::Transparent
#        }
}

if ($timer.IsEnabled){
$timer.Stop();
$btStart.Content="Start"
#$tbStatus.Text = "Paused`n" + $tbStatus.Text
} else {
#$timer.Interval = [TimeSpan]::fromseconds($cbInterval.Text)
$timer.Start()
$btStart.Content="Pause"
}

#UpdateStatus -now $now
})

$btReset.Add_Click({
if ($timer) { $timer.Stop()};
$btStart.Content="Start"
$viewModel.Stopped=$true
$viewModel.Running = New-Object Timespan
$pbStatus.Maximum=1

})

$btNow.add_Click({
$viewModel.EndTime = (Get-Date).AddHours(1)
})

#===========================================================================

function ExecText($command) {
try{
if ($command[0] -eq '"') { iex "& $command" }
else { iex $command }
$tbCmd.Background=[System.Windows.Media.Brushes]::Transparent
$viewModel.ExtraMsg=''
} catch {
Write-Host $_
$viewModel.ExtraMsg=$_
$tbCmd.Background=[System.Windows.Media.Brushes]::Red
}
}

function TimeReached(){
#$tbStatus.Text="Time Reached!"
#Shutdown.exe -t 30 -s
ExecText $tbCmd.Text
}

$btExec.Add_Click({
#Shutdown.exe -a
ExecText $tbCmd.Text
})

#===========================================================================
$Form.ShowDialog() | Out-Null

Advertisements
This entry was posted in C#, Powershell, XAML. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s