How To: Execute command line in C#, get STD OUT results

后端 未结 17 1267
既然无缘
既然无缘 2020-11-21 13:12

How do I execute a command-line program from C# and get back the STD OUT results? Specifically, I want to execute DIFF on two files that are programmatically selected and wr

相关标签:
17条回答
  • 2020-11-21 13:59

    Julian's solution is tested working with some minor corrections. The following is an example that also used https://sourceforge.net/projects/bat-to-exe/ GenericConsole.cs and https://www.codeproject.com/Articles/19225/Bat-file-compiler program.txt for args part:

    using System;
    using System.Text;  //StringBuilder
    using System.Diagnostics;
    using System.IO;
    
    
    class Program
    {
        private static bool redirectStandardOutput = true;
    
        private static string buildargument(string[] args)
        {
            StringBuilder arg = new StringBuilder();
            for (int i = 0; i < args.Length; i++)
            {
                arg.Append("\"" + args[i] + "\" ");
            }
    
            return arg.ToString();
        }
    
        static void Main(string[] args)
        {
            Process prc = new Process();
            prc.StartInfo = //new ProcessStartInfo("cmd.exe", String.Format("/c \"\"{0}\" {1}", Path.Combine(Environment.CurrentDirectory, "mapTargetIDToTargetNameA3.bat"), buildargument(args)));
            //new ProcessStartInfo(Path.Combine(Environment.CurrentDirectory, "mapTargetIDToTargetNameA3.bat"), buildargument(args));
            new ProcessStartInfo("mapTargetIDToTargetNameA3.bat");
            prc.StartInfo.Arguments = buildargument(args);
    
            prc.EnableRaisingEvents = true;
    
            if (redirectStandardOutput == true)
            {
                prc.StartInfo.UseShellExecute = false;
            }
            else
            {
                prc.StartInfo.UseShellExecute = true;
            }
    
            prc.StartInfo.CreateNoWindow = true;
    
            prc.OutputDataReceived += OnOutputDataRecived;
            prc.ErrorDataReceived += OnErrorDataReceived;
            //prc.Exited += OnExited;
    
            prc.StartInfo.RedirectStandardOutput = redirectStandardOutput;
            prc.StartInfo.RedirectStandardError = redirectStandardOutput;
    
            try
            {
                prc.Start();
                prc.BeginOutputReadLine();
                prc.BeginErrorReadLine();
                prc.WaitForExit();
            }
            catch (Exception e)
            {
                Console.WriteLine("OS error: " + e.Message);
            }
    
            prc.Close();
        }
    
        // Handle the dataevent
        private static void OnOutputDataRecived(object sender, DataReceivedEventArgs e)
        {
            //do something with your data
            Console.WriteLine(e.Data);
        }
    
        //Handle the error
        private static void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data);
        }
    
        // Handle Exited event and display process information.
        //private static void OnExited(object sender, System.EventArgs e)
        //{
        //    var process = sender as Process;
        //    if (process != null)
        //    {
        //        Console.WriteLine("ExitCode: " + process.ExitCode);
        //    }
        //    else
        //    {
        //        Console.WriteLine("Process exited");
        //    }
        //}
    }
    

    The code need to compile inside VS2007, using commandline csc.exe generated executable will not show console output correctly, or even crash with CLR20r3 error. Comment out the OnExited event process, the console output of the bat to exe will be more like the original bat console output.

    0 讨论(0)
  • 2020-11-21 14:03

    If you don't mind introducing a dependency, CliWrap can simplify this for you:

    var cli = new Cli("target.exe");
    var output = await cli.ExecuteAsync("arguments", "stdin");
    var stdout = output.StandardOutput;
    
    0 讨论(0)
  • 2020-11-21 14:03

    Since the most answers here dont implement the using statemant for IDisposable and some other stuff wich I think could be nessecary I will add this answer.

    For C# 8.0

    // Start a process with the filename or path with filename e.g. "cmd". Please note the 
    //using statemant
    using myProcess.StartInfo.FileName = "cmd";
    // add the arguments - Note add "/c" if you want to carry out tge  argument in cmd and  
    // terminate
    myProcess.StartInfo.Arguments = "/c dir";
    // Allows to raise events
    myProcess.EnableRaisingEvents = true;
    //hosted by the application itself to not open a black cmd window
    myProcess.StartInfo.UseShellExecute = false;
    myProcess.StartInfo.CreateNoWindow = true;
    // Eventhander for data
    myProcess.Exited += OnOutputDataRecived;
    // Eventhandler for error
    myProcess.ErrorDataReceived += OnErrorDataReceived;
    // Eventhandler wich fires when exited
    myProcess.Exited += OnExited;
    // Starts the process
    myProcess.Start();
    //read the output before you wait for exit
    myProcess.BeginOutputReadLine();
    // wait for the finish - this will block (leave this out if you dont want to wait for 
    // it, so it runs without blocking)
    process.WaitForExit();
    
    // Handle the dataevent
    private void OnOutputDataRecived(object sender, DataReceivedEventArgs e)
    {
        //do something with your data
        Trace.WriteLine(e.Data);
    }
    
    //Handle the error
    private void OnErrorDataReceived(object sender, DataReceivedEventArgs e)
    {        
        Trace.WriteLine(e.Data);
        //do something with your exception
        throw new Exception();
    }    
    
    // Handle Exited event and display process information.
    private void OnExited(object sender, System.EventArgs e)
    {
         Trace.WriteLine("Process exited");
    }
    
    0 讨论(0)
  • 2020-11-21 14:04

    This may not be the best/easiest way, but may be an option:

    When you execute from your code, add " > output.txt" and then read in the output.txt file.

    0 讨论(0)
  • 2020-11-21 14:07

    Here's a quick sample:

    //Create process
    System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
    
    //strCommand is path and file name of command to run
    pProcess.StartInfo.FileName = strCommand;
    
    //strCommandParameters are parameters to pass to program
    pProcess.StartInfo.Arguments = strCommandParameters;
    
    pProcess.StartInfo.UseShellExecute = false;
    
    //Set output of program to be written to process output stream
    pProcess.StartInfo.RedirectStandardOutput = true;   
    
    //Optional
    pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;
    
    //Start the process
    pProcess.Start();
    
    //Get program output
    string strOutput = pProcess.StandardOutput.ReadToEnd();
    
    //Wait for process to finish
    pProcess.WaitForExit();
    
    0 讨论(0)
  • 2020-11-21 14:07

    This might be useful for someone if your attempting to query the local ARP cache on a PC/Server.

    List<string[]> results = new List<string[]>();
    
            using (Process p = new Process())
            {
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.Arguments = "/c arp -a";
                p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
                p.Start();
    
                string line;
    
                while ((line = p.StandardOutput.ReadLine()) != null)
                {
                    if (line != "" && !line.Contains("Interface") && !line.Contains("Physical Address"))
                    {
                        var lineArr = line.Trim().Split(' ').Select(n => n).Where(n => !string.IsNullOrEmpty(n)).ToArray();
                        var arrResult = new string[]
                    {
                       lineArr[0],
                       lineArr[1],
                       lineArr[2]
                    };
                        results.Add(arrResult);
                    }
                }
    
                p.WaitForExit();
            }
    
    0 讨论(0)
提交回复
热议问题