Process.start: how to get the output?

后端 未结 9 1404
無奈伤痛
無奈伤痛 2020-11-21 23:56

I would like to run an external command line program from my Mono/.NET app. For example, I would like to run mencoder. Is it possible:

  1. To get
相关标签:
9条回答
  • 2020-11-22 00:37

    How to launch a process (such as a bat file, perl script, console program) and have its standard output displayed on a windows form:

    processCaller = new ProcessCaller(this);
    //processCaller.FileName = @"..\..\hello.bat";
    processCaller.FileName = @"commandline.exe";
    processCaller.Arguments = "";
    processCaller.StdErrReceived += new DataReceivedHandler(writeStreamInfo);
    processCaller.StdOutReceived += new DataReceivedHandler(writeStreamInfo);
    processCaller.Completed += new EventHandler(processCompletedOrCanceled);
    processCaller.Cancelled += new EventHandler(processCompletedOrCanceled);
    // processCaller.Failed += no event handler for this one, yet.
    
    this.richTextBox1.Text = "Started function.  Please stand by.." + Environment.NewLine;
    
    // the following function starts a process and returns immediately,
    // thus allowing the form to stay responsive.
    processCaller.Start();    
    

    You can find ProcessCaller on this link: Launching a process and displaying its standard output

    0 讨论(0)
  • 2020-11-22 00:39

    you can use shared memory for the 2 processes to communicate through, check out MemoryMappedFile

    you'll mainly create a memory mapped file mmf in the parent process using "using" statement then create the second process till it terminates and let it write the result to the mmf using BinaryWriter, then read the result from the mmf using the parent process, you can also pass the mmf name using command line arguments or hard code it.

    make sure when using the mapped file in the parent process that you make the child process write the result to the mapped file before the mapped file is released in the parent process

    Example: parent process

        private static void Main(string[] args)
        {
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("memfile", 128))
            {
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(512);
                }
    
                Console.WriteLine("Starting the child process");
                // Command line args are separated by a space
                Process p = Process.Start("ChildProcess.exe", "memfile");
    
                Console.WriteLine("Waiting child to die");
    
                p.WaitForExit();
                Console.WriteLine("Child died");
    
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryReader reader = new BinaryReader(stream);
                    Console.WriteLine("Result:" + reader.ReadInt32());
                }
            }
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    

    Child process

        private static void Main(string[] args)
        {
            Console.WriteLine("Child process started");
            string mmfName = args[0];
    
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(mmfName))
            {
                int readValue;
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryReader reader = new BinaryReader(stream);
                    Console.WriteLine("child reading: " + (readValue = reader.ReadInt32()));
                }
                using (MemoryMappedViewStream input = mmf.CreateViewStream())
                {
                    BinaryWriter writer = new BinaryWriter(input);
                    writer.Write(readValue * 2);
                }
            }
    
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
    

    to use this sample, you'll need to create a solution with 2 projects inside, then you take the build result of the child process from %childDir%/bin/debug and copy it to %parentDirectory%/bin/debug then run the parent project

    childDir and parentDirectory are the folder names of your projects on the pc good luck :)

    0 讨论(0)
  • 2020-11-22 00:47

    You can process your output synchronously or asynchronously.

    1. Synchronous example

    static void runCommand()
    {
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c DIR"; // Note the /c command (*)
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.Start();
        //* Read the output (or the error)
        string output = process.StandardOutput.ReadToEnd();
        Console.WriteLine(output);
        string err = process.StandardError.ReadToEnd();
        Console.WriteLine(err);
        process.WaitForExit();
    }
    

    Note that it's better to process both output and errors: they must be handled separately.

    (*) For some commands (here StartInfo.Arguments) you must add the /c directive, otherwise the process freezes in the WaitForExit().

    2. Asynchronous example

    static void runCommand() 
    {
        //* Create your Process
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c DIR";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        //* Set your output and error (asynchronous) handlers
        process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
        process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
        //* Start process and handlers
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        process.WaitForExit();
    }
    
    static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine) 
    {
        //* Do your stuff with the output (write to console/log/StringBuilder)
        Console.WriteLine(outLine.Data);
    }
    

    If you don't need to do complicate operations with the output, you can bypass the OutputHandler method, just adding the handlers directly inline:

    //* Set your output and error (asynchronous) handlers
    process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
    process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
    
    0 讨论(0)
  • 2020-11-22 00:52

    You can log process output using below code:

    ProcessStartInfo pinfo = new ProcessStartInfo(item);
    pinfo.CreateNoWindow = false;
    pinfo.UseShellExecute = true;
    pinfo.RedirectStandardOutput = true;
    pinfo.RedirectStandardInput = true;
    pinfo.RedirectStandardError = true;
    pinfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
    var p = Process.Start(pinfo);
    p.WaitForExit();
    Process process = Process.Start(new ProcessStartInfo((item + '>' + item + ".txt"))
    {
        UseShellExecute = false,
        RedirectStandardOutput = true
    });
    process.WaitForExit();
    string output = process.StandardOutput.ReadToEnd();
    if (process.ExitCode != 0) { 
    }
    
    0 讨论(0)
  • 2020-11-22 00:53

    The standard .NET way of doing this is to read from the Process' StandardOutput stream. There is an example in the linked MSDN docs. Similar, you can read from StandardError, and write to StandardInput.

    0 讨论(0)
  • 2020-11-22 00:56

    The solution that worked for me in win and linux is the folling

    // GET api/values
            [HttpGet("cifrado/{xml}")]
            public ActionResult<IEnumerable<string>> Cifrado(String xml)
            {
                String nombreXML = DateTime.Now.ToString("ddMMyyyyhhmmss").ToString();
                String archivo = "/app/files/"+nombreXML + ".XML";
                String comando = " --armor --recipient bibankingprd@bi.com.gt  --encrypt " + archivo;
                try{
                    System.IO.File.WriteAllText(archivo, xml);                
                    //String comando = "C:\\GnuPG\\bin\\gpg.exe --recipient licorera@local.com --armor --encrypt C:\\Users\\Administrador\\Documents\\pruebas\\nuevo.xml ";
                    ProcessStartInfo startInfo = new ProcessStartInfo() {FileName = "/usr/bin/gpg",  Arguments = comando }; 
                    Process proc = new Process() { StartInfo = startInfo, };
                    proc.StartInfo.RedirectStandardOutput = true;
                    proc.StartInfo.RedirectStandardError = true;
                    proc.Start();
                    proc.WaitForExit();
                    Console.WriteLine(proc.StandardOutput.ReadToEnd());
                    return new string[] { "Archivo encriptado", archivo + " - "+ comando};
                }catch (Exception exception){
                    return new string[] { archivo, "exception: "+exception.ToString() + " - "+ comando };
                }
            }
    
    0 讨论(0)
提交回复
热议问题