Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute multiple command lines with the same process using .NET

People also ask

Can you run 2 command prompts at once?

Click Start, type cmd, and press Enter to open a command prompt window. In the Windows taskbar, right-click the command prompt window icon and select Command Prompt. A second command prompt window is opened.

Can a batch script file run multiple commands at the same time?

You can use batch scripts to run multiple commands and instructions on your machine simultaneously. Using a batch script, you will be able to execute all your commands one by one automatically.

How do I run a DOS command in C#?

Process. Start("cmd.exe", @"/C md c:\test2"); Process. Start("cmd.exe", @"/C 'your command'");


You can redirect standard input and use a StreamWriter to write to it:

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

Couldn't you just write all the commands into a .cmd file in the temp folder and then execute that file?


As another answer alludes to under newer versions of Windows it seems to be necessary to read the standard output and/or standard error streams otherwise it will stall between commands. A neater way to do that instead of using delays is to use an async callback to consume output from the stream:

static void RunCommands(List<string> cmds, string workingDirectory = "")
{
    var process = new Process();
    var psi = new ProcessStartInfo();
    psi.FileName = "cmd.exe";
    psi.RedirectStandardInput = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;
    psi.WorkingDirectory = workingDirectory;
    process.StartInfo = psi;
    process.Start();
    process.OutputDataReceived += (sender, e) => { Console.WriteLine(e.Data); };
    process.ErrorDataReceived += (sender, e) => { Console.WriteLine(e.Data); };
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();
    using (StreamWriter sw = process.StandardInput)
    {
        foreach (var cmd in cmds)
        {
            sw.WriteLine (cmd);
        }
    }
    process.WaitForExit();
}

I prefer to do it by using a BAT file.

With BAT file you have more control and can do whatever you want.

string batFileName = path + @"\" + Guid.NewGuid() + ".bat";

using (StreamWriter batFile = new StreamWriter(batFileName))
{
    batFile.WriteLine($"YOUR COMMAND");
    batFile.WriteLine($"YOUR COMMAND");
    batFile.WriteLine($"YOUR COMMAND");
}

ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", "/c " + batFileName);
processStartInfo.UseShellExecute = true;
processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Normal;

Process p = new Process();
p.StartInfo = processStartInfo;
p.Start();
p.WaitForExit();

File.Delete(batFileName);

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

The && is the way to tell the command shell that there is another command to execute.