c#同时在cmd.exe中运行多个命令,并将输出写入文本文件

时间:2016-07-08 15:56:17

标签: c# .net-2.0

要求:

同时在cmd.exe中运行多个命令,并使用c#将输出写入单个文本文件,包括执行命令的开始时间和结束时间

请注意我想使用点网版2.0,因为此代码需要在XP等传统操作系统上运行。 Parallel和ConcurrentBag功能在.net 4.5版本

代码摘要:

  1. 创建一个字符串列表,其中包含要执行的所有命令。
  2. 遍历字符串列表并将命令作为参数传递给具有静态方法runCommand(字符串命令)的类

  3. 使用线程确保每个命令在一个单独的线程中并行执行。

  4. 问题:

    代码运行正常,但输出与写入控制台时所有命令的返回混淆,我确信写入文件时会出现同样的问题!我如何确保所有并行+输出的命令看起来整洁而不混淆。另请注意,当我尝试写入文件时,它会出错,因为多个进程正在尝试写入同一个文件。

    主要

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Text;
    using System.Threading;
    using BaileySoft.Utility;
    
    namespace Diagnostic_Commands
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                // Log file creation
                string strDestopPath = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
                strDestopPath += "\\Diagnostic_Today.txt";
                StreamWriter w = File.AppendText(strDestopPath);
    
                List<String> commands = new List<String>();
                commands.Add("nslookup www.google.com");
                commands.Add("Tracert -d  www.apple.com");         
                commands.Add("ipconfig /all");
                commands.Add("ping www.google.com -n 10");       
                commands.Add("nslookup www.apple.com");
    
    
                foreach (string cmd in commands)
                {
    
    
                        Thread tReturn = new Thread(() => { Test_Con.runCommand(cmd); });
                        tReturn.IsBackground = true;
                        tReturn.Priority = ThreadPriority.AboveNormal;
                        tReturn.IsBackground = true;
                        tReturn.Start();
    
                }
    
                Console.ReadLine();
    
    
            }
    
        }
    }
    

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Threading;
    
    public static class Test_Con
    {
        static string d = null;
    
        public static void runCommand(string command)
        {
            string starttime;
            string endtime;
    
            //* Create your Process
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/c" + command;
    
            starttime = "Started at " + DateTime.Now + "\n";
    
            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();
            endtime = "Completed at " + DateTime.Now + "\n";
    
            d+= "========================================================================";
            d+= starttime + endtime ;
    
            Console.WriteLine(d);
        }
        static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            //* Do your stuff with the output (write to console/log/StringBuilder)
            Console.WriteLine(outLine.Data); //This will keep writing all the command output irrespective    
    
        }
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

您可以使用Parallel和ConcurrentBag。 贝娄就是一个例子,但你必须改进它。

static void Main(string[] args)
        {
            // Log file creation
            var strDestopPath = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            strDestopPath += "\\Diagnostic_Today.txt";
            var w = File.AppendText(strDestopPath);

            var commands = new ConcurrentBag<string>();
            //List<String> commands = new List<String>();
            commands.Add("nslookup www.google.com");
            commands.Add("Tracert -d  www.apple.com");
            commands.Add("ipconfig /all");
            commands.Add("ping www.google.com -n 10");
            commands.Add("nslookup www.apple.com");

            var results = new ConcurrentBag<Tuple<string, string>>();

            Parallel.ForEach(commands, cmd => {
                new Test_Con(results).runCommand(cmd);
            });


            //Your results are here:
            foreach (var result in results)
            {
                Console.WriteLine("Command: {0}",result.Item1);
                Console.WriteLine("OutPut: {0}",result.Item1);
                Console.WriteLine("----------------------------");
            }

            Console.ReadLine();
        }
    }

    public class Test_Con
    {
        static string d = null;
        private ConcurrentBag<Tuple<string, string>> results;
        private string command;

        public Test_Con(ConcurrentBag<Tuple<string, string>> results)
        {
            this.results = results;
        }

        public void runCommand(string command)
        {
            this.command = command;
            string starttime;
            string endtime;

            //* Create your Process
            Process process = new Process();
            process.StartInfo.FileName = "cmd.exe";
            process.StartInfo.Arguments = "/c" + command;

            starttime = "Started at " + DateTime.Now + "\n";

            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();
            endtime = "Completed at " + DateTime.Now + "\n";

            d += "========================================================================";
            d += starttime + endtime;

            Console.WriteLine(d);
        }
        void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
        {
            //* Do your stuff with the output (write to console/log/StringBuilder)
            Console.WriteLine(outLine.Data); //This will keep writing all the command output irrespective    

            results.Add(new Tuple<string, string>( command, outLine.Data ));
        }

    }