Display output of the CMD in real time inside TextBox
Forum rules
Do not post any licensing information in this forum.
Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Do not post any licensing information in this forum.
Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Re: Display output of the CMD in real time inside TextBox
Here is how to make a full async read work in a form.
- Attachments
-
- Demo-Capture StandardOutAsync.psf
- (17.2 KiB) Downloaded 265 times
Re: Display output of the CMD in real time inside TextBox
If you don't set the $process.SynchronizingObject property, it will crash PowerShell. That was the issue I was having before.
David
SAPIEN Technologies, Inc.
SAPIEN Technologies, Inc.
Re: Display output of the CMD in real time inside TextBox
The exception is being missed by the scriptdriver. PowerShell CLI also misses the exception.
Faulting application name: scriptdriver64.exe, version: 1.4.48.0, time stamp: 0x5ae7594d
Faulting module name: KERNELBASE.dll, version: 10.0.17134.165, time stamp: 0xb0bb231d
Exception code: 0xe0434352
Fault offset: 0x000000000003a388
Faulting process id: 0x4dd0
Faulting application start time: 0x01d42f48f7837a64
Faulting application path: C:\Program Files (x86)\Common Files\SAPIEN Debugger 2018\scriptdriver64.exe
Faulting module path: C:\WINDOWS\System32\KERNELBASE.dll
Report Id: bd3e6bcf-7744-4b97-b1a6-c5b9b50365ce
Faulting package full name:
Faulting package-relative application ID:
- ALIENQuake
- Posts: 112
- Last visit: Mon Jan 29, 2024 7:35 am
- Has voted: 4 times
Re: Display output of the CMD in real time inside TextBox
Guys that looks amazing, let me digg into it and post back
- ALIENQuake
- Posts: 112
- Last visit: Mon Jan 29, 2024 7:35 am
- Has voted: 4 times
Re: Display output of the CMD in real time inside TextBox
I did it! Now I con not only display progress in real time but also send input if application suddenly ask for it! I'm using:
and it works. I didn't know much about process.EnableRaisingEvents and $process.SynchronizingObject so thank you for you help.
Code: Select all
$buttonSendInput_Click={
$process.StandardInput.WriteLine($textboxInput.Text)
}
Re: Display output of the CMD in real time inside TextBox
FYI, I plan to will integrate this into the Process Tracker Control Set in an upcoming service build.
David
SAPIEN Technologies, Inc.
SAPIEN Technologies, Inc.
- ALIENQuake
- Posts: 112
- Last visit: Mon Jan 29, 2024 7:35 am
- Has voted: 4 times
Re: Display output of the CMD in real time inside TextBox
davidc Thanks!
Do you think that it can solve yet another challenge? It's possible to wait for process exit?
Because I have two or more process, I want to execute them one by one (and at the same time, display output of the CMD in real time inside TextBox) and the next process has to wait for another because otherwise, it can't access/modify files in use. Sequence of the execution matters.
I can't use waitForExit() because it stops receiving output (works as design I think). Possible to achieve via extra Process Tracker or too good to be true?
I try to set $global:Monit = $true and wait for it to be false but usage of while of any kind [System.Threading.Thread]::Sleep(1000) is also preventing output/hang application.
Maybe I need to create new form for each process? Or add condition when there is no more OutputDataReceived ?
Do you think that it can solve yet another challenge? It's possible to wait for process exit?
Because I have two or more process, I want to execute them one by one (and at the same time, display output of the CMD in real time inside TextBox) and the next process has to wait for another because otherwise, it can't access/modify files in use. Sequence of the execution matters.
I can't use waitForExit() because it stops receiving output (works as design I think). Possible to achieve via extra Process Tracker or too good to be true?
I try to set $global:Monit = $true and wait for it to be false but usage of while of any kind [System.Threading.Thread]::Sleep(1000) is also preventing output/hang application.
Maybe I need to create new form for each process? Or add condition when there is no more OutputDataReceived ?
Last edited by ALIENQuake on Sat Sep 01, 2018 4:09 am, edited 1 time in total.
Re: Display output of the CMD in real time inside TextBox
The following can also be done in PowerShell:
- static Task<int> RunProcessAsync(string fileName){
- var tcs = new TaskCompletionSource<int>();
- var process = new Process {
- StartInfo = { FileName = fileName }, EnableRaisingEvents = true
- };
- process.Exited += (sender, args) => {
- tcs.SetResult(process.ExitCode);
- process.Dispose();
- };
- process.Start();
- return tcs.Task;
- }
- ALIENQuake
- Posts: 112
- Last visit: Mon Jan 29, 2024 7:35 am
- Has voted: 4 times
Re: Display output of the CMD in real time inside TextBox
This is what I've manage to create:
Code: Select all
$formAsyncPingerTest_Load = {
$pstart = 'SELECT * FROM Win32_ProcessStartTrace'
$pstop = 'SELECT * FROM Win32_ProcessStopTrace'
$action = {
$nevent = $Event.SourceEventArgs.NewEvent
if ($nevent.ProcessName -eq 'ping.exe' -and $Event.SourceIdentifier -eq 'Process.Stop') {
$global:processExited = $true
}
if ($nevent.ProcessName -eq 'nslookup.exe' -and $Event.SourceIdentifier -eq 'Process.Stop') {
$global:processExited = $true
}
}
Register-WmiEvent -Query $pstart -SourceIdentifier 'Process.Start' -Action $action
Register-WmiEvent -Query $pstop -SourceIdentifier 'Process.Stop' -Action $action
}
$global:process_OutputReceived = {
$global:processExited = $false
$textbox1.Lines += $_.Data
$textbox1.Select($textbox1.Text.Length, 0)
$textbox1.ScrollToCaret()
}
$global:process_Exited = {
$global:processExited = $true
Write-Host 'Exited'
Write-Host $global:processExited
}
$buttonPing_Click = {
'ping', 'ping' | % {
$script:process = New-Object System.Diagnostics.Process
$process.EnableRaisingEvents = $true
$process.StartInfo.RedirectStandardError = $true
$process.StartInfo.RedirectStandardOutput = $true
$process.StartInfo.RedirectStandardInput = $true
$process.StartInfo.FileName = $_
$process.StartInfo.RedirectStandardOutput = $true
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.CreateNoWindow = $true
$process.StartInfo.Arguments = '-n 5 google.com'
$process.add_OutputDataReceived($process_OutputReceived)
$process.add_Exited($process_Exited)
$process.SynchronizingObject = $formAsyncPingerTest
$global:processExited = $false
$process.Start() | Out-Null
$process.BeginOutputReadLine()
while ($global:processExited -eq $false) {
[System.Threading.Thread]::Sleep(1000)
Write-Host $global:processExited
}
}
}
$buttonStop_Click={
#TODO: Place custom script here
$process.CancelOutputRead()
$process.Kill()
$process.Dispose()
}
$formAsyncPingerTest_FormClosed=[System.Windows.Forms.FormClosedEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.FormClosedEventArgs]
#TODO: Place custom script here
$process.CancelOutputRead()
$process.Kill()
$process.Dispose()
Get-EventSubscriber | Unregister-Event -Force
}
2. at the start of the process, $global:processExited = $false
3. while $global:processExited = $false, wait before dealing with next object from array <-- this is where it hangs application
4. if OutputReceived , set $global:processExited = $false
5. if process_Exited, set $global:processExited = $true so while loop can continue
In theory, it should work but it hangs whole app and it doesn't display output in textbox. Without 'while' both process are executed at once. How to achieve this concept without using 'while'/blocking BeginOutputReadLine() ?
The c# static Task<int> RunProcessAsync code from you post is too complicated, maybe I will find powershell version of it but does it will suit my concept from above?The following can also be done in PowerShell: