Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
namespace PoshWpf.Data { | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Specialized; | ||
using System.Management.Automation; | ||
using System.Management.Automation.Runspaces; | ||
using System.Windows.Data; | ||
using System.Windows.Threading; | ||
using System.Collections.ObjectModel; | ||
|
||
[Cmdlet(VerbsCommon.New, "ScriptDataSource")] | ||
public class NewScriptDataSourceCommand : Cmdlet { | ||
[Parameter(Mandatory = true, Position = 0, HelpMessage = "A scriptblock to execute")] | ||
public ScriptBlock Script { get; set; } | ||
|
||
[Parameter(Mandatory = false, Position = 1, ParameterSetName = "Interval", HelpMessage = "Delay between re-running the script")] | ||
[Alias("TimeSpan","Every","Each")] | ||
public TimeSpan Interval { get; set; } | ||
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays"), | ||
Parameter(Mandatory = false, Position = 10, HelpMessage = "Input parameters to the ScriptBlock", ValueFromRemainingArguments = true, ValueFromPipeline = true)] | ||
[Alias("IO")] | ||
public PSObject[] InputObject { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter AccumulateOutput { get; set; } | ||
|
||
[Parameter(Mandatory = false)] | ||
public SwitchParameter LongRunning { get; set; } | ||
|
||
private List<PSObject> _input; | ||
protected override void BeginProcessing() { | ||
_input = new List<PSObject>(); | ||
base.BeginProcessing(); | ||
} | ||
protected override void ProcessRecord() { | ||
if (InputObject != null) | ||
_input.AddRange(InputObject); | ||
|
||
base.ProcessRecord(); | ||
} | ||
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] | ||
protected override void EndProcessing() { | ||
WriteObject(new ScriptDataSource(Script, _input, Interval, AccumulateOutput.ToBool(), LongRunning.ToBool())); | ||
|
||
base.EndProcessing(); | ||
} | ||
} | ||
|
||
public class ScriptDataSource : PSDataCollection<PSObject>, INotifyCollectionChanged { | ||
private readonly PowerShell _powerShellCommand; | ||
private readonly DispatcherTimer _timer; | ||
|
||
public ListCollectionView Progress { get; private set; } | ||
public ListCollectionView Verbose { get; private set; } | ||
public ListCollectionView Warning { get; private set; } | ||
public ListCollectionView Error { get; private set; } | ||
|
||
protected bool AccumulateOutput { get; set; } | ||
|
||
protected TimeSpan TimeSpan { get; set; } | ||
|
||
protected ScriptBlock Script { get; set; } | ||
|
||
public ScriptDataSource(ScriptBlock script) | ||
: this(script, null, new TimeSpan(), false, false) { } | ||
|
||
public ScriptDataSource(ScriptBlock script, IList<PSObject> input, TimeSpan interval, bool accumulateOutput, bool longRunning) | ||
: base() { | ||
|
||
Script = script; | ||
TimeSpan = TimeSpan.Zero; | ||
AccumulateOutput = accumulateOutput; | ||
|
||
_powerShellCommand = PowerShell.Create().AddScript(Script.ToString()); | ||
if (longRunning) { | ||
var runspace = RunspaceFactory.CreateRunspace(); | ||
runspace.Open(); | ||
_powerShellCommand.Runspace = runspace; | ||
} | ||
|
||
Error = new ListCollectionView(_powerShellCommand.Streams.Error); | ||
Warning = new ListCollectionView(_powerShellCommand.Streams.Warning); | ||
Verbose = new ListCollectionView(_powerShellCommand.Streams.Verbose); | ||
Progress = new ListCollectionView(_powerShellCommand.Streams.Progress); | ||
|
||
if (!longRunning) { | ||
Invoke(input).AsyncWaitHandle.WaitOne(); | ||
} | ||
|
||
if (TimeSpan.Zero < interval) { | ||
TimeSpan = interval; | ||
_timer = new DispatcherTimer(interval, DispatcherPriority.Normal, Invoke, Dispatcher.CurrentDispatcher); | ||
_timer.Start(); | ||
} | ||
} | ||
|
||
public void Start() { | ||
if (_timer != null) | ||
_timer.Start(); | ||
} | ||
|
||
public void Stop() { | ||
if (_timer != null) | ||
_timer.Stop(); | ||
} | ||
|
||
private void Invoke(object sender, EventArgs e) { | ||
if (PSInvocationState.Completed == _powerShellCommand.InvocationStateInfo.State || | ||
PSInvocationState.Stopped == _powerShellCommand.InvocationStateInfo.State || | ||
PSInvocationState.NotStarted == _powerShellCommand.InvocationStateInfo.State || | ||
PSInvocationState.Failed == _powerShellCommand.InvocationStateInfo.State) { | ||
Console.WriteLine("Tick"); | ||
Invoke(null); | ||
} | ||
else { | ||
Console.WriteLine("No Tick"); | ||
// string invocationSkipped = "Skipped Invocation Because the current InvocationState is " + _powerShellCommand.InvocationStateInfo.State + " (" + _powerShellCommand.InvocationStateInfo.Reason + ")"; | ||
if (Warning.CanAddNew) { | ||
var w = Warning.AddNew(); | ||
Console.WriteLine(w.GetType().FullName); | ||
Warning.CancelNew(); | ||
} | ||
} | ||
} | ||
|
||
public IAsyncResult Invoke(IList<PSObject> input) { | ||
using (var inputCollection = (input != null && input.Count > 0) | ||
? new PSDataCollection<PSObject>(input) | ||
: new PSDataCollection<PSObject>()) { | ||
Console.WriteLine("There were " + this.Count); | ||
|
||
if (!AccumulateOutput) { | ||
Clear(); | ||
} | ||
|
||
return _powerShellCommand.BeginInvoke<PSObject, PSObject>(inputCollection, this, new PSInvocationSettings(), (e) => { | ||
if (CollectionChanged != null) { | ||
Console.WriteLine("There are " + this.Count); | ||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); | ||
} | ||
}, null); | ||
} | ||
} | ||
|
||
public event NotifyCollectionChangedEventHandler CollectionChanged; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
function New-PowerChart() { | ||
#.Synopsis | ||
# Create a chart using the WPF DataVisualization Toolkit (WPFToolkit) | ||
#.Example | ||
# New-PowerChart Area { ls | ? {!$_.PSIsContainer} } -IndependentValue Name -DependentValue Length -Show | ||
#.Example | ||
# New-PowerChart Pie { ps | sort WS -desc | select -first 10 } Name WS -Show -Interval "0:0:5" | ||
#.Notes | ||
# This should probably be replaced with something based on OxyPlot, | ||
# WPFToolkit charting never made it out of the roadmap/preview phase. | ||
[CmdletBinding(DefaultParameterSetName='DataTemplate')] | ||
param( | ||
[Parameter(Position=0, Mandatory=$true)] | ||
[ValidateSet("Area","Bar","Bubble","Column","Line","Pie","Scatter")] | ||
[String[]] | ||
${ChartType} | ||
, | ||
[Parameter(Position=1, Mandatory=$true, HelpMessage='The data for the chart ...')] | ||
[System.Management.Automation.ScriptBlock[]] | ||
${ItemsSource} | ||
, | ||
[Parameter(Position=2, Mandatory=$true, HelpMessage='The property name for the independent values ...')] | ||
[String[]] | ||
${IndependentValuePath} | ||
, | ||
[Parameter(Position=3, Mandatory=$true, HelpMessage='The property name for the dependent values ...')] | ||
[String[]] | ||
${DependentValuePath} | ||
, | ||
[Parameter(Position=4, HelpMessage='The property name for the size values ...')] | ||
[String[]] | ||
${SizeValuePath} | ||
, | ||
[TimeSpan] | ||
${Interval} | ||
, | ||
[Switch] | ||
$Show | ||
) | ||
begin | ||
{ | ||
Chart -ControlNale PowerChart -Tag @{Interval=$Interval; ItemsSource=$ItemsSource} -On_Loaded { | ||
$Interval = $this.Tag.Interval | ||
if($Interval) { | ||
Register-PowerShellCommand -ScriptBlock { | ||
$i=0 | ||
$Window.Content.Series | ForEach{ $_.ItemsSource = &$($Window.Content.Tag.ItemsSource[$i++]) } | ||
} -in $Interval -run | ||
} | ||
} -Series { | ||
$Series = @() | ||
# Write-Host "Three" -Fore Cyan | ||
for($c=0; $c -lt $ChartType.length; $c++) { | ||
$ChartType[$c] = $ChartType[$c].ToLower() | ||
if($SizeValuePath -and $ChartType[$c] -eq "Bubble") { | ||
$Series += iex "$($chartType)Series -DependentValuePath $($DependentValuePath[$c]) -IndependentValuePath $($IndependentValuePath[$c]) -SizeValuePath $($SizeValuePath[$c]) -ItemsSource `$(&{$($ItemsSource[$c])})" | ||
#$Series[-1].DataPointStyle = $this.FindResource("$($chartType)DataPointTooltipsFix") | ||
} elseif($ChartType[$c] -eq "Pie") { | ||
$Series += iex "$($chartType)Series -DependentValuePath $($DependentValuePath[$c]) -IndependentValuePath $($IndependentValuePath[$c]) -ItemsSource `$(&{$($ItemsSource[$c])})" | ||
#$Series[-1].StylePalette = $this.FindResource("$($chartType)PaletteTooltipsFix") | ||
} else { | ||
Write-Verbose "$($chartType)Series -DependentValuePath $($DependentValuePath[$c]) -IndependentValuePath $($IndependentValuePath[$c]) -ItemsSource `$(&{$($ItemsSource[$c])})" | ||
$Series += iex "$($chartType)Series -DependentValuePath $($DependentValuePath[$c]) -IndependentValuePath $($IndependentValuePath[$c]) -ItemsSource `$(&{$($ItemsSource[$c])})" | ||
#A$Series[-1].DataPointStyle = $this.FindResource("$($chartType)DataPointTooltipsFix") | ||
} | ||
} | ||
Write-Verbose "There are $($Series.Count) Series!" | ||
$Series | ||
} -Background Transparent -BorderThickness 0 -Show:$Show | ||
} | ||
} |