【问题标题】:Best way to interact with Command Line application与命令行应用程序交互的最佳方式
【发布时间】:2010-10-01 08:34:36
【问题描述】:

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

过去有没有人取得过类似的成就?如果是这样,你是怎么做的?你有没有注意到一种模式,或者可能有一些好的内置类可以使用?干杯!

【问题讨论】:

    标签: c# windows .net-3.5


    【解决方案1】:

    您需要使用Process 重定向输入和输出流;处理两者都稍微有点棘手,因为您需要小心不要在缓冲区中丢失东西(导致死锁)。

    您可能还想查看OutputDataReceived 以获取基于事件的响应。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        当我的回复只是指向其他地方的链接时,我会感到厌烦。我看不出 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();
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-30
          • 2018-03-16
          • 2010-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-18
          • 1970-01-01
          相关资源
          最近更新 更多