I need to write a component for an application that interacts tightly with a command line application. The command line application asks a series of questions, performs some computations, then terminates (which i need to detect). Essentially, i want to wrap up this interaction in a wrapper class.
Has any one achieved similar in the past? If so, how did you go about it? Did you notice a pattern, or maybe some good build in classes to use? Cheers!
Open Visual Studio, and choose Create a new project in the Start window. In the Create a new project window, select All languages, and then choose C# from the dropdown list. Choose Windows from the All platforms list, and choose Console from the All project types list.
The command line (aka Terminal or Command Prompt) refers to a type of program that comes preinstalled with Windows, Linux and Mac computers and allows you to execute commands, run programs and navigate through the folders on your computer.
Terminal, or the command line interface (CLI), is considered by many to be the Holy Grail of computer management. At one time the CLI was the only way to accomplish anything on a computer; then, the CLI gave way to the graphical user interface (GUI) as the popularity of PCs increased.
You would need to redirect both the input and output streams, using Process
; it is slightly trickier handling both, since you need to be careful that things aren't lost in the buffers (causing deadlock).
You might also want to look at OutputDataReceived for event-based responses.
I get dinged when my responses are just links to elsewhere. I don't see where the link to the C# Corner article helps much.
The question is 10 years old today but it should have been clarified. The question does not specify whether there are line endings (CrLf) at the end of each question. Assuming there are, as in the following:
string Answer;
Console.Out.WriteLine("First question: ");
Answer = Console.In.ReadLine();
Console.Out.WriteLine("Another question: ");
Answer = Console.In.ReadLine();
Console.Out.WriteLine("Final question: ");
Answer = Console.In.ReadLine();
Then the following can be used to respond to it:
class Program
{
const string FirstQuestion = "First question: ";
const string SecondQuestion = "Another question: ";
const string FinalQuestion = "Final question: ";
static AutoResetEvent Done = new AutoResetEvent(false);
static void Main(string[] args)
{
const string TheProgram = @" ... ";
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo(TheProgram);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
p.StartInfo = psi;
Console.WriteLine("Executing " + TheProgram);
p.Start();
DoPromptsAsync(p);
Done.WaitOne();
}
private static async Task DoPromptsAsync(Process p)
{
StreamWriter sw = p.StandardInput;
StreamReader sr = p.StandardOutput;
string Question;
Question = await sr.ReadLineAsync();
if (Question != FirstQuestion)
return;
sw.WriteLine("First answer");
Console.WriteLine(Question + "answered");
Question = await sr.ReadLineAsync();
if (Question != SecondQuestion)
return;
sw.WriteLine("Second answer");
Console.WriteLine(Question + "answered");
Question = await sr.ReadLineAsync();
if (Question != FinalQuestion)
return;
sw.WriteLine("Final answer");
Console.WriteLine(Question + "answered");
Done.Set();
}
}
The following works in a WPF application; I used a double-click event to test but this could be used in other WPF events.
const string TheProgram = @" ... ";
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo(TheProgram);
psi.UseShellExecute = false;
//psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
p.StartInfo = psi;
p.Start();
const string FirstQuestion = "First question: ";
const string SecondQuestion = "Another question: ";
const string FinalQuestion = "Final question: ";
StreamWriter sw = p.StandardInput;
StreamReader sr = p.StandardOutput;
string Question;
StringBuilder sb = new StringBuilder("Executing " + TheProgram + "\r\n");
Question = await sr.ReadLineAsync();
if (Question != FirstQuestion)
return;
sw.WriteLine("First answer");
sb.Append(Question + "answered\r\n");
Question = await sr.ReadLineAsync();
if (Question != SecondQuestion)
return;
sw.WriteLine("Second answer");
sb.Append(Question + "answered\r\n");
Question = await sr.ReadLineAsync();
if (Question != FinalQuestion)
return;
sw.WriteLine("Final answer");
sb.Append(Question + "answered\r\n");
ResultBox.Text = sb.ToString();
I think it will be more complicated if there are not line endings after each question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With