【问题标题】:Reading/Writing to a command line program in c#在 C# 中读取/写入命令行程序
【发布时间】:2014-01-21 22:58:48
【问题描述】:

我正在尝试与 C# 中的命令行程序对话。它是一个情绪分析器。它的工作原理是这样的:

CMD> java -jar analyser.jar

>Starting analyser...

{这是我想从我的 c# 程序中插入东西的地方。例如:}

I love you!

{程序响应 - 我想读这个}

Very Positive

这是一些伪代码:

Process.start("sentiment.exe");
Process.writeline("I love you");
string Response = Process.readline();

C# 提供了哪些方法来写入进程的标准输入并从其标准输出中读取?

【问题讨论】:

  • 你的问题是......?
  • 不清楚你在问什么?
  • 也许您正在寻找| 将一个程序的输出链接到另一个程序,例如type my.txt | more...一般cmd /? 会解决很多与之相关的问题。
  • 我添加了一些示例代码。
  • 读取标准输出,查看:Process.BeginOutputReadLine msdn.microsoft.com/en-us/library/… 写入标准输入:Process.StandardInput.WriteLine()

标签: c# shell cmd


【解决方案1】:

您要做的是为您正在启动的进程“重定向”标准输入和输出通道。这将允许您通过 C# 流读取和写入子进程。

为此,您首先需要在用于启动子进程的ProcessStartInfo 类中设置RedirectStandardInput 和RedirectStandardOutput 字段:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "otherprogram.exe";
p.Start();

完成后,p.StandardInput 和 p.StandardOutput 将是附加到子进程输入和输出的 StreamReaders。根据子进程的确切输入和输出,您可能需要小心避免死锁(例如,您的程序正在等待输出而另一个程序正在等待输入)。为避免这种情况,如果需要,您可以使用BeginOutputReadLine 方法异步接收输出。

【讨论】:

  • +1。这是一个很好的起点。正如 Michael Edenfield 在答案中指出的那样,必须注意实际阅读输出 - 搜索类似的问题(即提及 RedirectStandardInput)以获取完整的示例/解决方案。
【解决方案2】:

这是一个小演示,展示了如何按照您的要求进行操作。

这是一个玩具命令行应用程序,它只是从标准输入读取并回显到标准输出:

class Echoer
{
    static void Main(string[] args)
    {
        while (true)
        {
            var input = Console.ReadLine();
            Console.WriteLine("Echoing: " + input);
        }
    }
}

这是另一个命令行应用程序,它运行上述应用程序,将输入传递给它,并读取它的输出:

class Program
{
    static void Main(string[] args)
    {
        ProcessStartInfo processStartInfo;
        processStartInfo = new ProcessStartInfo();
        processStartInfo.CreateNoWindow = true;

        // Redirect IO to allow us to read and write to it.
        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.RedirectStandardInput = true;
        processStartInfo.UseShellExecute = false;

        processStartInfo.FileName = @"path\to\your\Echoer.exe";

        Process process = new Process();
        process.StartInfo = processStartInfo;
        process.Start();
        int counter = 0;
        while (counter < 10)
        {
            // Write to the process's standard input.
            process.StandardInput.WriteLine(counter.ToString());

            // Read from the process's standard output.
            var output = process.StandardOutput.ReadLine();
            Console.WriteLine("Hosted process said: " + output);
            counter++;
        }

        process.Kill();

        Console.WriteLine("Hit any key to exit.");
        Console.ReadKey();
    }
}

如果您托管的应用程序不是简单地生成一行输出来响应一行输入,那么您可以查看使用 Process.BeginOutputReadLine 异步捕获输出(链接文档中有示例代码)。

【讨论】:

    【解决方案3】:

    这不是一个普遍的问题,而是一个特定于应用程序的问题。我只是碰巧在做同样的事情。我们可能不应该在这里讨论这个,但请原谅我只是想帮忙。

    关键是你需要为jar输入正确的参数

    var processInfo = new ProcessStartInfo("java.exe", "-jar SentiStrengthCom.jar stdin sentidata data201109/ scale"){ ... }
    

    以下是一个可行的解决方案:

        // Start the java server, probably in a background thread
        void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            string directory = ...; // the directory of jar
    
            var processInfo = new ProcessStartInfo("java.exe", "-jar SentiStrengthCom.jar stdin sentidata data201109/ scale")
            {
                // Initialize properties of "processInfo"
                CreateNoWindow = true,
                UseShellExecute = false, 
                WorkingDirectory = directory,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
            };
    
            JavaSentiStrength = new Process();
            JavaSentiStrength.StartInfo = processInfo;
    
            JavaSentiStrength.Start();
    
            Console.WriteLine("SentiStrengthCom Java is running...");
    
            JavaSentiStrength.WaitForExit();
    
            int exitCode = 0;
            if (JavaSentiStrength != null) exitCode = JavaSentiStrength.ExitCode;
            Debug.WriteLine("Java SentiStrengthCom closed down! " + exitCode);
            JavaSentiStrength.Close();
            JavaSentiStrength = null;
    
        }
    
        // A button click
        private void btnRequest_Click(object sender, EventArgs e)
        {
            JavaSentiStrength.StandardInput.WriteLine("love you ");
            string s_out = JavaSentiStrength.StandardOutput.ReadLine();
            Debug.WriteLine("SentiStrengthCom output: " + s_out);
        }
    

    输出是

    SentiStrengthCom 输出:3 -1 2

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 2022-01-21
      • 1970-01-01
      • 2022-11-02
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      相关资源
      最近更新 更多