using this Code
Process process = new Process();
// p.EnableRaisingEvents = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.LoadUserProfile = false;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = #"C:\putty.exe"; ; // Gets or sets the application or document to start.
process.StartInfo.Arguments = "-serial com31 -sercfg 9600,8,n,1,N";//Gets or sets the set of command-line arguments to use when starting the application
Thread.Sleep(1000);
process.Start();//Starts (or reuses) the process resource that is specified by the StartInfo property of this Process component and associates it with the component.
process.BeginOutputReadLine();
process.WaitForExit(); // wait forever with ping
I'm trying to open putty in console application , but any timr I use it it opens in New windows and I cant get to output of the process using process.OutputDataReceived event
I'm using code very similar to this to open Iperf and it works fine
What am I missing here ?
Putty is not a console application and therefore does not provide output on it's stdout and stderr streams.
And since it is a windowed application it does not care whether you start it with the CreateNoWindow flag. Try and start notepad.exe with that flag, you will see it appearing obviously.
There is however a programm by the creators of Putty that provides the functionality you need.
It's called Plink.exe and you can download it on their homepage
Related
I am trying to automate HandbrakeCLI using C# via the System.Diagnostics.Process class. However, as long as my program is trying to run the process, it seems like the process never advances.
Here is my process setup:
Process process = new System.Diagnostics.Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = parameters.HandbrakeLocation;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
string output = string.Empty;
while ((output = process.StandardOutput.ReadLine()) != null)
{
Debug.WriteLine(output);
}
process.WaitForExit();
HandbrakeCLI.exe does appear in my processes list. The Debug.WriteLine(output); line continually prints out "Encoding: task 1 of 1, 0.00 %" and the process never completes. If I kill my C# app then HandbrakeCLI instantly shoots up from 7,000k in memory to 145,000k and then does the encoding that I want it to do. Its like my C# app is holding it back.
I have tried to use Read() instead of ReadLine() and I have tried flushing the StandardOutput stream before and after the read with no success. I have a suspicion that since HandbrakeCLI overwrites stdout when it writes the encoding progress, that it won't act like a normal process when automated via C#.
I figured it out. I was redirecting stderr to my C# application, but not consuming it. The process was hanging until stderr was consumed.
I have a complete command line application in c# which has different modules and depends on multiple dlls etc.
Now, i want to call that CLI app with an another UI app. But the issue is that the Thread part of the CLI applicaiton is not working and the control just jumps to the end. So, is there any way I can handle this scenario?
For example: I have app CLI.exe which i want to call so i have written following code:
Process proc = new Process();
proc.StartInfo.FileName = CLI.exe;
proc.StartInfo.Arguments = args;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
proc.WaitForExit();
Now this calls the app i want to call. The following code is there in my app CLI.exe
System.Console.WriteLine("Start app {0}", args);
do
{
System.Threading.Thread.Sleep(1000);
} while (model.Exited == false);
System.Console.WriteLine("Finish app");
Now, in between the do while loop, I do a lot pf processing while the model.exit don't get false.
But it starts the app, writes the Start app message and just after that it writes the Finish app and the processing in between never happened.
model.Exit also went true without processing.
Also, if I run the CLI.exe with the batch command or run the CLI.exe on cmd it runs perfectly.
So, any idea as how to manage this?
proc.WaitForExit(); freezes your process until child process is finished. Remove that and handle process exit in another way, for example, using events:
proc.EnableRaisingEvents = true;
proc.Exited += OnExit;
I have an application that I would like to call from C#, using something like:
Process process = new Process();
process.StartInfo.FileName = exe;
process.StartInfo.Arguments = args;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataHandler);
process.OutputDataReceived += new DataReceivedEventHandler(OutputDataHandler);
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
I know in advance that the application invoked has a gui and may throw up model dialog boxes. The way I am invoking the application the gui will never be needed and will run to completion. A model dialog box is thrown up at the end simply asking the user is they want to close the gui (since it was invoked to run automatically).
Is there a way to invoke the app from c# such that
a) The modal dialog boxes are ignored?
b) No GUI is actually shown?
Ultimtely I want to run the external app with no interruption before it returns control to my app.
EDIT: More clarification. I don't own the 3rd party app, so I have no control on how it behaves.
I want to use shell executable in order to respect user preferences of application to be started, but I also need to know when that particular application is closed.
Process editProcess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = filename;
startInfo.Verb = "edit";
startInfo.UseShellExecute = true;
editProcess.StartInfo = startInfo;
// start the default editor
editProcess.Start();
editProcess.WaitForExit();
WaitForExit seems to return when the shell process exits and not when the real process exits.
Is there a better way of knowing when started application is exited than manually parsing registry, finding correct application to start and explicitly start that app without shell execute?
Handle the process exited event:
editProcess.Exited += process_Exited;
I am using the Process class to run an exe.
The exe is a 3rd party console application that I do not control.
I wish to know whether the process is waiting for input on the command line.
Should it make any difference, I intend to kill the application should it be waiting for input.
There are suitable events for when there is output from the program waiting to be read, but I cannot see anything similar for when the process is waiting patiently for input.
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "myapp.exe";
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
process.StartInfo = info;
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
How do I detect that my process is waiting for input?
Depending on what the 3rd party process is doing exactly you could try polling its threads' states:
foreach(ProcessThread thread in process.Threads)
if (thread.ThreadState == ThreadState.Wait
&& thread.WaitReason == ThreadWaitReason.UserRequest)
process.Kill();
Failing that... you can try to
process.StandardInput.Close();
after calling Start(), I conjecture that an exception will be raised in the child process if it's trying to read from standard input.
If the console application has some sort of prompt waiting for input, you could periodically parse out the console output text using the Process.StandardOutput property of the process and wait for said prompt. Once the proper string is detected, you know that it's waiting for input. See http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx.
Use process.StandardInput.writrLine("input");
for sending input to consol in c#