user5720776
user5720776

Reputation: 1

How to interact with cmd.exe using C#?

I want to call cmd.exe using C#. And I want to write multiple cmd commands in C#.

the most important keys is that: I want to interact with cmd window.the next command is typed according to the last command output.

But now I have tried ,it can input multiple commands but only one output or one outputErr.

I want to achieve one command one output,and the next command is also the same cmd window rather than a new cmd window?

How to solve this problem. the example code is like this

string[] message = new string[2];

ProcessStartInfo info = new ProcessStartInfo();

info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;

info.UseShellExecute = false;
info.FileName = "cmd.exe";
info.CreateNoWindow = true;

Process proc = new Process();
proc.StartInfo = info;
proc.Start();

using (StreamWriter writer = proc.StandardInput)
{
    if (writer.BaseStream.CanWrite)
    {
        foreach (string q in command)
        {
            writer.WriteLine(q);
        }
        writer.WriteLine("exit");
    }
}

message[0] = proc.StandardError.ReadToEnd();

if (output)
{
    message[1] = proc.StandardOutput.ReadToEnd();
}

return message;

Upvotes: 0

Views: 1624

Answers (1)

xeon_pan
xeon_pan

Reputation: 51

The problem is that cmd is a cli application, so proc.StandardOutput.ReadToEnd() will block your thread, you can't simply put the ReadToEnd() in your loop (to execute multiple command).

In my demo, I start a new thread to handle the output.so that i won't block my command input.

  var proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                CreateNoWindow = true
            }
        };
        proc.Start();
        StringBuilder sb = new StringBuilder();
        var outStream = proc.StandardOutput;
        var inStream = proc.StandardInput;
        inStream.WriteLine("mkdir test");
        Task.Run(() =>
        {
            while (true)
            {
                Console.WriteLine(outStream.ReadLine());
            }
        });
        Console.WriteLine("dir");
        inStream.WriteLine("dir");

        Console.WriteLine("mkdir test");
        inStream.WriteLine("mkdir test");

        Console.WriteLine("dir");
        inStream.WriteLine("dir");
        Console.ReadLine();

    }

forgive my poor english,

Upvotes: 3

Related Questions