$wpfTypes = Add-Type -AssemblyName PresentationFramework -PassThru
$windowsBaseTypes = Add-Type -AssemblyName WindowsBase -PassThru
$windowsBaseAssembly = $windowsBaseTypes[0].Assembly.Location
$wpfAssembly = $wpfTypes[0].Assembly.Location
$presentationCoreTypes = Add-Type -AssemblyName PresentationCore -PassThru
$presentationCoreAssembly = $presentationCoreTypes[0].Assembly.Location
$systemXamlTypes = Add-Type -AssemblyName System.Xaml -PassThru
$systemXamlAssembly = $systemXamlTypes[0].Assembly.Location
if ('OutputHelper' -as [type]) { return } else {
Add-Type -TypeDefinition @'
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
public class OutputHelper
{
public OutputHelper(Window window, TextBox textBox, DispatcherPriority priority)
{
Handler = (s, e) => {
window.Dispatcher.Invoke(() => textBox.AppendText(e.Data + "\n"), priority);
};
}
public DataReceivedEventHandler Handler { get; private set; }
}
'@ -ReferencedAssemblies $wpfAssembly, $windowsBaseAssembly, $presentationCoreAssembly, $systemXamlAssembly, System.Diagnostics.Process
}
$Xaml = New-Object System.Xml.XmlNodeReader([XML]@"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" WindowStartupLocation="CenterScreen" ShowInTaskbar="True">
<Grid>
<TextBox x:Name="TextBox"/>
</Grid>
</Window>
"@)
Function Start-Worker {
$TextBox = $Window.FindName("TextBox")
$SyncHash = [hashtable]::Synchronized(@{Window = $Window; TextBox = $TextBox})
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable("SyncHash", $SyncHash)
$Worker = [PowerShell]::Create().AddScript({
Start-Transcript
$process = New-Object System.Diagnostics.Process
$process.StartInfo.FileName = 'ping.exe'
$process.StartInfo.Arguments = 'google.com -n 5'
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.CreateNoWindow = $true
$process.StartInfo.RedirectStandardInput = $false
$process.StartInfo.RedirectStandardOutput = $true
$process.EnableRaisingEvents = $true
$process.add_OutputDataReceived(
[OutputHelper]::new($SyncHash.Window, $SyncHash.TextBox, "ContextIdle").Handler
#$SyncHash.Window.Dispatcher.Invoke( [action] { $SyncHash.TextBox.AppendText($_.Data) }, [System.Windows.Threading.DispatcherPriority]::ContextIdle )
#$SyncHash.Window.Dispatcher.Invoke( [System.Windows.Forms.MethodInvoker] { $SyncHash.TextBox.AppendText($_.Data) }, [System.Windows.Threading.DispatcherPriority]::ContextIdle )
#$SyncHash.TextBox.Dispatcher.Invoke( [action] { $SyncHash.TextBox.AppendText($_.Data) }, [System.Windows.Threading.DispatcherPriority]::ContextIdle )
#$SyncHash.TextBox.Dispatcher.Invoke( [System.Windows.Forms.MethodInvoker] { $SyncHash.TextBox.AppendText($_.Data) }, [System.Windows.Threading.DispatcherPriority]::ContextIdle )
#$SyncHash.Window.Dispatcher.Invoke( "ContextIdle", [action]{ $SyncHash.TextBox.AppendText($_.Data) } )
#$SyncHash.TextBox.Dispatcher.Invoke( [System.Windows.Threading.DispatcherPriority]::ContextIdle, [System.Windows.Forms.MethodInvoker]{ $SyncHash.TextBox.AppendText($_.Data) } )
)
$process.Start() | Out-Null
$process.BeginOutputReadLine()
$process.WaitForExit()
Stop-Transcript
})
$Worker.Runspace = $Runspace
$Worker.BeginInvoke()
}
$script:Window = [Windows.Markup.XamlReader]::Load($Xaml)
$script:TextBox = $Window.FindName("TextBox")
$Window.Add_Loaded({ Start-Worker })
[Void]$Window.ShowDialog()