要求:
同时在cmd.exe中运行多个命令,并使用c#将输出写入单个文本文件,包括执行命令的开始时间和结束时间
请注意我想使用点网版2.0,因为此代码需要在XP等传统操作系统上运行。 Parallel和ConcurrentBag功能在.net 4.5版本
下代码摘要:
遍历字符串列表并将命令作为参数传递给具有静态方法runCommand(字符串命令)的类
使用线程确保每个命令在一个单独的线程中并行执行。
问题:
代码运行正常,但输出与写入控制台时所有命令的返回混淆,我确信写入文件时会出现同样的问题!我如何确保所有并行+输出的命令看起来整洁而不混淆。另请注意,当我尝试写入文件时,它会出错,因为多个进程正在尝试写入同一个文件。
主要
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
}
}
}
答案 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 ));
}
}