c# how pass parameters to process OutputHandler? - c#

I am open some process and read its output and I want to pass this function another param:
public void Start(string fileName, string arguments)
{
Process process = new Process();
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
private void OutputHandler(object sender, DataReceivedEventArgs e)
{
App.Current.Dispatcher.Invoke((Action)delegate
{
string line = e.Data;
if (line != null)
{
}
});
}

Related

c# Run python script and read output lead to

I want to run python script but my problem is that i get all the output at once at the end and not line by line (my script print the time 10 times and sleep for 1 second after each time).
This is my code:
static void Main(string[] args)
{
string cmd = #"C:\test.py";
string pythonPath = #"C:\python.exe";
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = pythonPath;//cmd is full path to python.exe
start.Arguments = cmd;//args is path to .py file and any cmd line args
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
while (!process.StandardOutput.EndOfStream)
{
string result = process.StandardOutput.ReadLine();
Console.Write(result);
}
}
}
}
UPDATE
string cmd = #"C:\test.py";
string pythonPath = #"C:\Python37\python.exe";
Process process = new Process();
process.StartInfo.FileName = "python";
process.StartInfo.Arguments = cmd;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
private static void OutputHandler(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
Python script
import time
from datetime import datetime
count = 0
while count < 3:
print(datetime.now())
time.sleep(1)
count += 1
print('DONE')

C# get EventHandler process information

I start a few processes and I want to know which process called the OutputHandler, but I can’t get any information about the sending process.
When I try to read a property, it always throws a InvalidOperationException
void ExecString()
{
using (Process process = new Process())
{
process.StartInfo.FileName = executeExe;
process.StartInfo.Arguments = string.Format("{0}/{1}#{2} #{3}", parameter0, parameter1, parameter2, parameter3);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += OutputHandler;
process.Start();
process.BeginOutputReadLine();
}
}
void OutputHandler(object sendingProcess, DataReceivedEventArgs output)
{
try
{
OutputText = output.Data;
var tmpProcess = (Process)sendingProcess;
var testId = tmpProcess.Id; // Throw Exception
}
catch (InvalidOperationException e)
{
OutputText = e.Message;
}
}
Could you try this, It may help you;
Process currentProcess = Process.GetCurrentProcess();
var pid = currentProcess.Id;

StringBuilder crash with ArgumentOutOfRangeException

I have a crash in Event Viewer with this:
Exception Info: System.ArgumentOutOfRangeException
at System.Text.StringBuilder.ToString()
at XXX.BrainActions+<>c__DisplayClass11_0.<runApp>b__0(System.Object,
System.EventArgs)
The offending code is this, why is StringBuilder causing this exception?
Process process = new Process();
StringBuilder builder = new StringBuilder();
try
{
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.FileName = filename;
process.StartInfo.Arguments = arguments;
process.StartInfo.WorkingDirectory = Themes.getInstance().getScriptPath();
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.EnableRaisingEvents = true;
process.Exited += new EventHandler((object sender, System.EventArgs e) => {
string consoleOutput = builder.ToString();
if (!String.IsNullOrWhiteSpace(consoleOutput))
{
Log.INFO("XXX", String.Format("Console output: {0}", builder.ToString()));
}
processesRunning.Remove(process);
if (callbacks != null)
{
callbacks.ActionCompleted(action);
if (processesRunning.Count == 0)
{
callbacks.AllActionsCompleted();
}
}
});
process.Start();
process.PriorityClass = ProcessPriorityClass.High;
process.OutputDataReceived += (sender, args) => builder.Append(args.Data);
process.ErrorDataReceived += (sender, args) => builder.Append(args.Data);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
processesRunning.Add(process);
}
catch (Exception e)
{
}
StringBuilder is used to basically get the output of the external process and log it to the console using Log4net which is basically wrapped in the Log() function. Any ideas? Note that this crash rarely happens I've only seen it once but once is a reason to fix it.

Why isn't all the data fron Standard Output and Error not received in wpf application however it is in a console application?

When you call the RedirectCommandStream in the code below it works perfectly in a console application, however in a wpf application it misses out the standard output data and some of the standard error output. The string builder that is outputed from the method is then used to display on the wpf application.
Can someone please help, been stuck on this for a long time?
class ProcessStreamRedirection
{
private static StringBuilder OutputBuilder = null;
public static StringBuilder RedirectCommandStreams(string FileName,string Arguments)
{
Process Process;
Process = new Process();
Process.StartInfo.FileName = FileName;
Process.StartInfo.Arguments = Arguments;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.RedirectStandardOutput = true;
Process.StartInfo.CreateNoWindow = false;
Process.OutputDataReceived += new DataReceivedEventHandler(DataHandler);
OutputBuilder = new StringBuilder();
Process.StartInfo.RedirectStandardError = true;
Process.ErrorDataReceived += new DataReceivedEventHandler(DataHandler);
OutputBuilder.AppendLine(string.Format("Starting process: {0} {1}", Process.StartInfo.FileName ,Process.StartInfo.Arguments));
Process.Start();
Process.BeginOutputReadLine();
Process.BeginErrorReadLine();
Process.WaitForExit();
if (OutputBuilder.Length > 0)
{
OutputBuilder.AppendLine(string.Format("Output:\n{0}\n", OutputBuilder));
}
Process.Close();
return OutputBuilder;
}
private static void DataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
OutputBuilder.AppendLine(outLine.Data);
}
}
}

calling a ruby script in c#

How do make a call to a ruby script and pass some parameters and once the script is finished return the control back to the c# code with the result?
void runScript()
{
using (Process p = new Process())
{
ProcessStartInfo info = new ProcessStartInfo("ruby C:\rubyscript.rb");
info.Arguments = "args"; // set args
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
string output = p.StandardOutput.ReadToEnd();
// process output
}
}
Just to fill smaller gaps I've implemented the same functionallity with ability to access OutputStream asynchronously.
public void RunScript(string script, string arguments, out string errorMessage)
{
errorMessage = string.empty;
using ( Process process = new Process() )
{
process.OutputDataReceived += process_OutputDataReceived;
ProcessStartInfo info = new ProcessStartInfo(script);
info.Arguments = String.Join(" ", arguments);
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo = info;
process.EnableRaisingEvents = true;
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
errorMessage = process.StandardError.ReadToEnd();
}
}
private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
using ( AutoResetEvent errorWaitHandle = new AutoResetEvent(false) )
{
if ( !string.IsNullOrEmpty(e.Data) )
{
// Write the output somewhere
}
}
}

Categories

Resources