output limitation when calling exe file from c# code - c#

I have an exe file that I call it from my c# code by using Process namespace in c#.
I catch output by using ReadToEnd() method. (in exe source code i used a print method for my desired output).
the problem is when my output is getting larger the executing of exe file is got crashed and hanged.
Is there any limitation of output size when calling exe function?
Process p = new Process();
p.StartInfo.FileName = command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Arguments = args;
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
return output;

What you're experiencing is a deadlock. That situation is described in the documentation. In order to avoid it, make sure you read the output before waiting for the child process to exit.
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();

I remember having the same problem as you're describing here, and what I did back then was something like this:
private string RunProcess(string command, string args)
{
StringBuilder sb = new StringBuilder();
Process p = new Process();
p.StartInfo.FileName = command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Arguments = args;
p.OutputDataReceived += (sender, eventArgs) => { sb.Append(eventArgs.Data); };
p.Start();
p.WaitForExit();
return sb.ToString();
}

Related

Start process and get its output constantly

I have a console program written in c++, and I would like to continually check its output to use in my c# project.
This is the code I've tried to steal from another StackOverflow question, but with no luck.
Edit:( By no luck, I mean: the output is pretty much empty, although if I set p.StartInfo.CreateNoWindow to false, I can see my script.exe launch and output into its window. )
Process p = new Process();
p.StartInfo.FileName = #"external\script.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);
I had a similar issue and it had to do with where the output was going. The solution was to run cmd and execute my script from the cmd process. See this answer to another question for more information. reading from stdout and stderr together Your new code would look like:
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c yourscriptpath.exe 2>&1";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine("Output:");
Console.WriteLine(output);

How to start a process in the background and read standard output

I am new to C#, I have to start a very time consuming process from my C# program of course without bearing the loss of ui freeze, also I want to read the output printed by the program in cmd and at last I want a stop button so that I can close the program whenever I want...
Please help..
try:
using System.Diagnostics;
void startProcess()
{
Process p = new Process();
p.StartInfo.FileName = "FileName";
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
var output = p.StandardOutput.ReadToEnd();
}
MethodInvoker starter = new MethodInvoker(startProcess);
starter.BeginInvoke(null, null);
for ending the process:
p.close()
Use something like this:
void StartProcess(){
Process p = new Process();
p.StartInfo.FileName = "yourfile.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
var readingThread = new System.Threading.Thread(() => {
while (!p.StandardOutput.EndOfStream){
Console.WriteLine(p.StandartOutput.ReadLine());
System.Threading.Thread.Sleep(1);
}
}
readingThread.Start();
}

Copying CMD output to clipboard

I'm trying to copy output from a program running out of the CMD prompt to the Windows clipboard.
private void button1_Click(object sender, EventArgs e)
{
/*Relevant Code*/
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = String.Format("/k cd {0} && backdoor -rt -on -s{1} -p{2}", backdoorDir, pSN, sPPC);
p.Start();
p.WaitForExit();
string result = p.StandardOutput.ReadToEnd();
System.Windows.Forms.Clipboard.SetText(result);
}
If I were to enter this directly into CMD, it would look like this:
First Command (change directory):
cd C:\users\chris\appdata\roaming\backdoor
Second Command (Launches backdoor, a cmd tool. Arguments follow.):
backdoor -rt -on -sCCDXE -p14453
And when doing this through CMD, I get this result:
The backdoor password is: 34765
C:\users\chris\appdata\roaming\backdoor>
However, when running my C# code, this is the only thing that gets added to my clipboard:
C:\users\chris\appdata\roaming\backdoor>
Why isn't it capturing "The backdoor password is: 34765?" It's like the p.StandardOutput.ReadToEnd() isn't reading everything.
Call ReadToEnd before WaitForExit
Chris' code:
private void button1_Click(object sender, EventArgs e)
{
/*Relevant Code*/
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = String.Format("/k cd {0} && backdoor -rt -on -s{1} -p{2}", backdoorDir, pSN, sPPC);
p.Start();
string result = p.StandardOutput.ReadToEnd();
p.WaitForExit();
System.Windows.Forms.Clipboard.SetText(result);
}
Sample console app code:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C dir";
p.Start();
string result = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(result);
Console.ReadLine();
argument /C executes the command and then terminates the cmd process. This is necessary for this code to work. Otherwise, it will wait for ever.
One reson may well be that the program is not actually writing to StdOut but to the screen directly.
Test this by piping the output into a file:
backdoor -rt -on -sCCDXE -p14453 > c:\text.txt
If the new file doesn't contain the output either then you are stuck and may need to look into screen scraping..

Cannot get the output of command line in c#

I want to get the output of an execution in c# and I referred to this question. But I only have the output be printed on the console but not stored in the specified string. Here is my code: `
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
//p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "ffmpeg.exe";
p.StartInfo.Arguments = " -i 1.flv";
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
Console.WriteLine(output);
Console.ReadLine();`
The output string is still empty after the execution of these codes. Plus if I keep the line p.StartInfo.CreateNoWindow = true;, no words will be printed on the console at all, why this happen? I thought the line will only stop a new window being created.
Move string output = p.StandardOutput.ReadToEnd(); inside wait for exit.
How are you going to read data when it already exit.
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
//p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "ffmpeg.exe";
p.StartInfo.Arguments = " -i 1.flv";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Console.WriteLine(output);
Console.ReadLine();`
I'd try the following:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "ffmpeg.exe";
p.StartInfo.Arguments = " -i 1.flv";
p.Start();
while (!p.HasExited)
{
string output = p.StandardOutput.ReadToEnd();
}
I also suggest you have a look at the BeginReadOutputLine method in this example given in the MS documentation. Being asynchronous, it will be called even though you use WaitForExit.
A boiled down version of this is:
// Start the asynchronous read of the output stream.
p.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
p.EnableRaisingEvents = true;
p.BeginOutputReadLine();
p.Start();
p.WaitForExit();
p.Close();
private static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
// Collect the command output.
if (!String.IsNullOrEmpty(outLine.Data))
{
numOutputLines++;
// Add the text to the output
Console.WriteLine(Environment.NewLine +
"[" + numOutputLines.ToString() + "] - " + outLine.Data);
}
}
How about switch those two line?
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();

Redirect process output C#

I would like to redirect the Process's standard output to a string for later parsing.
I would also like to see the output on the screen, while the process is running, and not only when it finishes it's run.
Is that even possible?
Use RedirectStandardOutput.
Sample from MSDN:
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Also see OutputDataReceived and BeginOutputReadLine() for an alternative to ReadToEnd(), that will better fulfill your "see output while the process is running" requirement.
If you want to execute an exe from your c# application and get the output from it then you can use the below code
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = "PATH TO YOUR FILE";
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = metalType + " " + graphHeight + " " + graphWidth;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.EnableRaisingEvents = true;
p.Start();
svgText = p.StandardOutput.ReadToEnd();
using(StreamReader s = p.StandardError)
{
string error = s.ReadToEnd();
p.WaitForExit(20000);
}
Don't forgete to write p.EnableRaisingEvents = true;

Categories