使用.NET以相同的过程执行多个命令行

我试图执行多个命令,而不是每次创build一个新的进程。 基本上,我想启动DOS命令shell,切换到MySQL命令shell,并执行命令。 以下是我如何调用过程(也在下面)。 另外,如何处理命令中的“\”?

ExecuteCommand("mysql --user=root --password=sa casemanager", 100, false); ExecuteCommand(@"\. " + Environment.CurrentDirectory + @"\MySQL\CaseManager.sql", 100, true); private void ExecuteCommand(string Command, int Timeout, Boolean closeProcess) { ProcessStartInfo ProcessInfo; Process Process; ProcessInfo = new ProcessStartInfo("cmd.exe", "/C " + Command); ProcessInfo.CreateNoWindow = false; ProcessInfo.UseShellExecute = false; Process = Process.Start(ProcessInfo); Process.WaitForExit(Timeout); if (closeProcess == true) { Process.Close(); } } 

您可以redirect标准input并使用StreamWriter来写入:

  Process p = new Process(); ProcessStartInfo info = new ProcessStartInfo(); info.FileName = "cmd.exe"; info.RedirectStandardInput = true; info.UseShellExecute = false; p.StartInfo = info; p.Start(); using (StreamWriter sw = p.StandardInput) { if (sw.BaseStream.CanWrite) { sw.WriteLine("mysql -u root -p"); sw.WriteLine("mypassword"); sw.WriteLine("use mydb;"); } } 
 const string strCmdText = "/C command1&command2"; Process.Start("CMD.exe", strCmdText); 

难道你不能只把所有的命令写入临时文件夹中的.cmd文件,然后执行该文件吗?

 ProcessStartInfo pStartInfo = new ProcessStartInfo(); pStartInfo.FileName = "CMD"; pStartInfo.Arguments = @"/C mysql --user=root --password=sa casemanager && \. " + Environment.CurrentDirectory + @"\MySQL\CaseManager.sql" pStartInfo.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(pStartInfo); 

&&是告诉命令shell还有另外一个命令要执行的方法。

一个命令行进程如cmd.exemysql.exe通常会读取(并执行)你(用户)键入的任何内容(在键盘上)。

为了模仿这一点,我想你想使用RedirectStandardInput属性: http : //msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardinput.aspx

样品分析
比方说,我们正在这样玩。 就像我们在控制台上键入一样。

  new CmdShell() .Execute(@" none_existing_command /oops ping example.com -n 5 ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsMSBuildCmd.bat"" CD ""C:\My Projects\Some Solution"" MsBuild SomeProject.csproj^ /target:Build^ /p:Configuration=Release^ /verbosity:normal^ /maxCpuCount none_existing_command /oops ECHO ErrorLever = %ERRORLEVEL% " )); 

和一个捆绑

 public class CmdShell { public void Execute(string cmdCommands) { var commandsList = cmdCommands.Split(new[] { Environment.NewLine }, StringSplitOptions.None); var info = new ProcessStartInfo { FileName = "cmd.exe", // The Process object must have the UseShellExecute property set to false in order to redirect IO streams. UseShellExecute = false, RedirectStandardInput = true, RedirectStandardError = true, RedirectStandardOutput = true }; var proc = new Process(); // The "using" is more safe alternative for "proc.Close()" to release resources. using (proc) { proc.StartInfo = info; proc.Start(); // This could be useful for somebody to use async reads if you wish. //proc.BeginOutputReadLine //proc.BeginErrorReadLine commandsList.ToList() .ForEach(command => proc .StandardInput.WriteLine(command)); // Allow not-blocking use of ReadToEnd(). // Use the CMD EXIT command vs "proc.StandardInput.Close()" to pass the exit code to .NET proc.ExitCode below; proc.StandardInput.WriteLine("EXIT"); // At this point, the used CMD process does not exist anymore. var waitSeconds = 600; var interrupted = !proc.WaitForExit(waitSeconds * 1000); if (interrupted) { //throw new Exception(string.Format("Was interrupted after waiting for {0} seconds.", waitSeconds)); } var output = proc.StandardOutput.ReadToEnd(); var errorOutput = proc.StandardError.ReadToEnd(); var exitCode = proc.ExitCode; if (exitCode != 0) { // STUB: Remove the return. return; throw new Exception(string.Format(@"Error exit code {0} received. Error Output: {1} Output: {2} ", exitCode, errorOutput, output )); } } } } 

你也可以告诉MySQL执行给定文件中的命令,如下所示:

 mysql --user=root --password=sa casemanager < CaseManager.sql 

在发送另一个命令之前,您需要从input中读取所有数据!

如果没有数据可用,你不能要求阅读…一点点吸不是?

我的解决scheme…当要求阅读…要求读一个大的缓冲区…像1 MEGA …

你将需要等待100毫秒…示例代码…

 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim oProcess As New Process() Dim oStartInfo As New ProcessStartInfo("cmd.exe", "") oStartInfo.UseShellExecute = False oStartInfo.RedirectStandardOutput = True oStartInfo.RedirectStandardInput = True oStartInfo.CreateNoWindow = True oProcess.StartInfo = oStartInfo oProcess.Start() Dim Response As String = String.Empty Dim BuffSize As Integer = 1024 * 1024 Dim x As Char() = New Char(BuffSize - 1) {} Dim bytesRead As Integer = 0 oProcess.StandardInput.WriteLine("dir") Threading.Thread.Sleep(100) bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize) Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead)) MsgBox(Response) Response = String.Empty oProcess.StandardInput.WriteLine("dir c:\") Threading.Thread.Sleep(100) bytesRead = 0 bytesRead = oProcess.StandardOutput.Read(x, 0, BuffSize) Response = String.Concat(Response, String.Join("", x).Substring(0, bytesRead)) MsgBox(Response) End Sub End Class