与命令行应用程序交互的最佳方式

时间:2009-01-14 11:47:58

标签: c# windows .net-3.5

我需要为与命令行应用程序紧密交互的应用程序编写组件。命令行应用程序询问一系列问题,执行一些计算,然后终止(我需要检测)。基本上,我想在包装类中结束这种交互。

过去有没有人取得过相似的成绩?如果是这样,你是怎么做到的?您是否注意到一个模式,或者可能在类中使用一些好的构建?干杯!

3 个答案:

答案 0 :(得分:15)

您需要使用Process重定向输入和输出流;处理两者都稍微复杂一些,因为你需要注意缓冲区中的东西不会丢失(导致死锁)。

您可能还想查看OutputDataReceived基于事件的回复。

答案 1 :(得分:1)

如果所有应用程序都是使用dotnet开发的,您可以使用Assembly class

答案 2 :(得分:0)

当我的回答只是指向其他地方的链接时,我会感到沮丧。我看不到C#Corner文章的链接有什么帮助。

这个问题今天已经有10年了,但应该已经澄清了。该问题未指定每个问题末尾是否有行尾(CrLf)。假设有如下所示:

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();

然后可以使用以下方法对此进行响应:

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();
    }
}

以下内容在WPF应用程序中有效;我使用了双击事件进行测试,但这可以在其他WPF事件中使用。

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();

如果每个问题后面都没有行尾,我认为这会更加复杂。