Reading/Writing to a command line program in c#

后端 未结 3 725
夕颜
夕颜 2021-01-16 00:09

I\'m trying to talk to a command-line program from C#. It is a sentiment analyser. It works like this:

CMD> java -jar analyser.jar

>

相关标签:
3条回答
  • 2021-01-16 00:20

    This is not a general question, but rather a application-specific one. I just happened to be working on the same thing. We probably should not discuss about this here, but forgive me I just want to help.

    The key point is that you need to enter the right arguments for the jar

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

    Below is a working solution:

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

    The output is

    SentiStrengthCom output: 3 -1 2

    Hope it helps!

    0 讨论(0)
  • 2021-01-16 00:23

    What you're trying to do is to "redirect" the standard input and output channels for the process that you're launching. This will allow you to read from and write to the child process via C# streams.

    To do so, you first need to set the RedirectStandardInput and RedirectStandardOutput fields in the ProcessStartInfo class you use to start the child process:

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

    Once that's done, p.StandardInput and p.StandardOutput will be StreamReaders that are attached to the input and output of the child process. Depending on the exact input and output of the child process, you may need to be careful to avoid deadlocking (where your program is waiting for output while the other program is waiting for input, as an example). To avoid that, you can use the BeginOutputReadLine method to receive output asynchronously, if needed.

    0 讨论(0)
  • 2021-01-16 00:29

    Here's a little demo showing how to do what you are asking.

    This is a toy command line app that just reads from standard input and echos back to standard output:

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

    This is another command line app that runs the above app, passing input to it, and reading its output:

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

    If the app you are hosting does not simply produce a line of output in response to a line of input, then you can look at capturing output asynchronously using Process.BeginOutputReadLine (there's example code in the linked documentation).

    0 讨论(0)
提交回复
热议问题