I'm developing a C# application and I need to run an external console process (for example a python script) and receive the output data of the script in real-time. The python script is something like this:
import time
while 1:
print("Hi Foo!")
time.sleep(.3)
The following C# code prints the python script output on the C# console in real-time:
static void Main(string[] args)
{
using (Process process = new Process())
{
process.StartInfo.FileName = "python.exe";
process.StartInfo.Arguments = "test.py";
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
}
}
However, when I try to capture the output data and write them on the console manually, I fail. The recommended solution according to other posts is something like this, but it doesn't work:
static void Main(string[] args)
{
using (Process process = new Process())
{
process.StartInfo.FileName = "python.exe";
process.StartInfo.Arguments = "test.py";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
}
The process.StandardOutput.ReadToEnd() works in blocking mode waiting for the process to exit and returns the whole output all at once. What exactly is the problem with the real-time output capturing and how can I fix it?
using (var process = new Process())
{
process.StartInfo.FileName = #"python.exe";
process.StartInfo.Arguments = "-u test.py";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
string line = process.StandardOutput.ReadLine();
Console.WriteLine(line);
// do something with line
}
process.WaitForExit();
Console.Read();
}
Related
I have a program which start a batch process. This batch file is a consuming process and I want to return the result while the process is running. I try to use await and async but nothing works.
result = String.Empty;
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = RunText;
startinfo.Arguments = "cmd";
Process process = new Process();
process.StartInfo = startinfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
while (!process.StandardOutput.EndOfStream)
{
result = process.StandardOutput.ReadLine();//I want to return the result
Console.WriteLine(result);
}
-This is my batch program. The output is 1 if there is a connection with another PC.
#echo off
:begin
for /F "tokens=*" %%L in ('netstat -n ^| find ":3389" ^| find "ESTABLISHED" /c') do (set "VAR=%%L")
echo %VAR%
goto begin
I am beginner with this topics(processes and multi-threading). Any help would be greatly appreciated.
Use handlers to achieve this:
public static void MyHandler(object process, DataReceivedEventArgs dataReceived)
{
if (!String.IsNullOrEmpty(dataReceived.Data))
{
// do something you want here, for an example
Console.WriteLine(dataReceived.Data);
}
}
And in main method:
//...
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(MyHandler);
process.Start();
I need to send an input from a C# program to another program and capture its process's output every time after the input is sent
Here I wrote a C program to be used as a process in C# program. The program will receive an input and print back the same string
#include <stdio.h>
#include <stdbool.h>
int main(){
while(true){
char buff[1000];
scanf(" %[^\n]s", buff);
printf("\nechoed : %s\n",buff);
}
}
This is my C# program that will send input and receive output to and from my C program
(I am starting the process in another thread so process.WaitForExit() will not block the main thread)
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace MinExample
{
internal class Program
{
static StreamWriter processStreamWriter;
static string filePath = #"my_program.exe";
private static void MyProcOutputHandler(object sendingProcess,
DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
Console.WriteLine("Data : " + outLine.Data);
}
}
//this doesn't works
static void StartProcessWithOutputRedirection()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = filePath;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
//standard input out redirection
startInfo.RedirectStandardOutput = true;//redirect output
startInfo.RedirectStandardError = true;//redirect output
startInfo.RedirectStandardInput = true;
try
{
//Initialize process and register callback
Process process = new Process();
process.StartInfo = startInfo;
process.OutputDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
//
process.Start();
//initialize stream writer so that the process can receive incoming input
processStreamWriter = process.StandardInput;
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
//this works
static void StartProcessNoOutputRedirection()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = filePath;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
//standard input out redirection
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardInput = true;
try
{
//Initialize process and set property
Process process = new Process();
process.StartInfo = startInfo;
//
process.Start();
//initialize stream writer so that the process can receive incoming input
processStreamWriter = process.StandardInput;
process.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void Main(string[] args)
{
/*
using StartProcessNoOutputRedirection works but using StartProcessWithOutputRedirection doesn't
*/
ThreadStart ths = new ThreadStart(StartProcessWithOutputRedirection);
Thread th = new Thread(ths);
th.Start();
while (true)
{
Console.Write("Input :");
string input = Console.ReadLine() ?? "";
processStreamWriter.WriteLine(input);
}
}
}
}
It will print the output each time the process receives an output when I don't redirect the output at all
However when I tried to redirect the output, the Process.OutputDataReceived event isn't being called back. I have searched another post and have tried to use process.BeginOutputReadLine(); after process.Start but it hasn't solved my issue
Any advice?
c-sharpers, I am trying to use "System.Diagnostics.Process" to open the firefox app, but can't figure it out in ubuntu 20.04
main.cs
using var process = new Process();
process.StartInfo.FileName="/lib/firefox/firefox.sh";
process.StartInfo.UseShellExecute = false;
process.Start();
After the execution of the code above, nothing happens no error no dust ??
The solution that I found is to add "Thread.sleep()" .
static void Main(string[] args)
{
using var process = new Process();
process.StartInfo.FileName="/usr/lib/firefox/firefox.sh";
process.StartInfo.UseShellExecute = false;
process.Start();
Thread.Sleep(1000);
}
I wrote a simple TCP Server application,
when the program gets the request it will call an exe file to do something.
The application works fine on my PC.
But when I run on another PC the thread will stuck because it stuck in process start, so I checked the task manager whether the exe file did run. and it really work.
I have no idea how to solve it.
Here is my code:
System.Diagnostics.Process process = new System.Diagnostics.Process();
string path = System.Environment.CurrentDirectory;
process.StartInfo.WorkingDirectory = path;
process.StartInfo.FileName = "FileTransferTool\\FileTransfer.exe";
process.StartInfo.Arguments = argument;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.CreateNoWindow = false;
process.Start(); // the thread stuck here
I print out the message, it shows
System.ComponentModel.Win32Exception (0x80004005):
The system cannot find the file specified at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startIn
fo)
at System.Diagnostics.Process.Start() at ClassPackage.DsUploadFiletoNC.Start(Object[] param)
I have solved this problem by adding another process to call cmd.exe on the top of the main program, the code shown as below :
And the program will run as Administrator, but I don't know why
static void Main(string[] args)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
string path = System.Environment.CurrentDirectory;
process.StartInfo.WorkingDirectory = #"C:\Windows\System32";
process.StartInfo.FileName = "cmd.exe";
//process.StartInfo.FileName = "FileTransferTool\\circle.txt";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardInput = true;
//process.StartInfo.CreateNoWindow = false;
process.Start();
using (TCPServer server = new TCPServer())
{
server.Start();
Console.WriteLine("Socket Server Start...");
Console.ReadKey(true);
}
}
I am trying to exec Python from c# using process.BeginOutputReadLine()
My problem is that the receive result from python only show when the python prog is finished and not really seems to perform readline
here is my code
public void ExecuteProcess()
{
using (var process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = "python.exe";
process.StartInfo.Arguments = string.Format("{0} ", #"C:\FB\mytestpython.py");
process.OutputDataReceived += (sender, args) =>
{
if (args.Data != null)
{
//write data
UpdatePythonLog(args.Data);
}
};
process.Start();
process.BeginOutputReadLine();
}
return ;
}
and here is my Python code:
import time
if __name__=='__main__':
print "test1"
time.sleep(5)
print "test2"
time.sleep(5)
print "test3"
time.sleep(5)
print 'finish'