Ejecuta múltiples líneas de comando con el mismo proceso usando .NET

Estoy intentando ejecutar varios comandos sin crear un nuevo proceso cada vez. Básicamente, quiero iniciar el shell de comandos de DOS, cambiar al shell de comandos de MySQL y ejecutar un comando. Así es como estoy llamando al procedimiento (también a continuación). Además, ¿cómo manejo las “\” ‘s en el comando?

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(); } } 

Puede redirigir la entrada estándar y usar StreamWriter para escribir en ella:

  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); 

¿No podría simplemente escribir todos los comandos en un archivo .cmd en la carpeta temporal y luego ejecutar ese archivo?

 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); 

El && es la forma de decirle al shell del comando que hay otro comando para ejecutar.

Un proceso de línea de comandos como cmd.exe o mysql.exe generalmente leerá (y ejecutará) lo que sea que el usuario (el usuario) escriba (en el teclado).

Para imitar eso, creo que desea utilizar la propiedad RedirectStandardInput : http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardinput.aspx

¡Necesita LEER TODOS los datos de la entrada, antes de enviar otro comando!

Y no puedes pedir LEER si no hay datos disponibles … ¿no es poco?

Mis soluciones … cuando piden leer … piden leer un gran buffer … como 1 MEGA …

Y necesitarás esperar un mínimo de 100 milisegundos … código de muestra …

 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 

También podría decirle a MySQL que ejecute los comandos en el archivo dado, así:

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