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);
Related
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();
}
As part of my program I need to run a batch file.
The person I'm doing it for doesn't want anyone to be able to view the batch script, so I tried to include it in a WinForms solution, but I can't get it to run, I just get a time out error.
Michael,
You can do it two different way.
To provide script file in Process, but it will expose your code, as its open in file.
You can start command prompt by your process and supply your code as an argument.
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
OR
var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = #"/c dir \windows";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = false;
p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data);
p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data);
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();
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..
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;
I've the below code where I use DevCon.exe to capture something and write it in a file. I parse this file for a need.
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C devcon.exe find = port *monitor* > monitor_Details.txt";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Verb = "runas";
p.Start();
Unfortunately, with this code, I dont see any textfile created. So, here shell commands are not considered though I mentioned.
Same command is working in CMDLine.
Can anyone pls help as to what's going wrong?
I tried with below code as well and it does not work.
Process p = new Process();
p.StartInfo.FileName = "devcon.exe";
p.StartInfo.Arguments = "find = port *monitor* > monitor_Details.txt";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = true;
p.StartInfo.Verb = "runas";
p.Start();
You can add theses lines - based on RedirectStandardOutput
p.StartInfo.RedirectStandardOutput = true;
.....
p.Start();
string result = p.StandardOutput.ReadToEnd();
Link : http://msdn.microsoft.com/fr-fr/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx
I had the exact same problem. A workaround is to provide the UserName and Password parameters for the process as well as the "runas" verb. This will make the new process start elevated and be able to Read/Write files. I don't have clear explanation but it worked for me.
p.StartInfo.Verb = "runas";
p.StartInfo.UserName = Environment.UserName;
p.StartInfo.Password = PromptUserPassword(); //Get password as SecureString