0

As title. I want to do something to DOCKER on a server with no DOCKER DESKTOP easily, so I've read How To: Execute command line in C#, get STD OUT results , and I make my code as this:

CmdProcess = new Process();
CmdProcess.StartInfo.FileName = "cmd.exe";
CmdProcess.StartInfo.CreateNoWindow = true;  
CmdProcess.StartInfo.UseShellExecute = false; 
CmdProcess.StartInfo.RedirectStandardInput = true; 
CmdProcess.StartInfo.RedirectStandardOutput = true;
CmdProcess.StartInfo.RedirectStandardError = true;
CmdProcess.Start();
CmdProcess.StandardInput.WriteLine("/K docker images");
output = CmdProcess.StandardOutput.ReadToEnd();
if (output != string.Empty)
{
    MessageBox.Show(output, "Docker Image Show", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
    MessageBox.Show("No data", "Docker Image Show", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

and I got stuck at the line to get output value, no response, just like running into a infinite loop. Could someone guide me to solve this?

Gary Lu
  • 75
  • 1
  • 1
  • 5

2 Answers2

2

You're not starting the program you think you're starting.

CmdProcess.StartInfo.FileName = "cmd.exe";
// ...
CmdProcess.StandardInput.WriteLine("/K docker images");

What this does is start a shell prompt (cmd.exe) and then send the string "/K docker images" to the input. When I try doing that manually, I get

'/k' is not recognized as an internal or external command, operable program or batch file.

The reason you are not seeing that message is probably because this is printed to the standard error, not the standard output, and you're not creating a window (which may be useful to do as long as you're debugging). Make sure you also read the error stream! To read both streams at the same time, you'll need to do it asynchronously as shown in this answer by Cameron.

What you need to do is either 'type in' the command that you want at the prompt:

CmdProcess.StartInfo.FileName = "cmd.exe";
CmdProcess.Start();
// ...
CmdProcess.StandardInput.WriteLine("docker images");
//                                ^^^ no /K here

or better, use StartInfo.Arguments to pass in the argument:

CmdProcess.StartInfo.FileName = "cmd.exe";
CmdProcess.StartInfo.Arguments = "/K docker images";
CmdProcess.Start();

Also, note that cmd is never going to exit when you use /K, you may want to use /C instead:

/C      Carries out the command specified by string and then terminates
/K      Carries out the command specified by string but remains
Jazz.
  • 458
  • 4
  • 12
CompuChip
  • 9,143
  • 4
  • 24
  • 48
0

You want to execute the docker images command and read its output in your C# application. The issue with your code is that you're using "/K" with WriteLine, which is incorrect. You can fix your code by using /C flag and passing it as an argument to cmd.exe:

string output;
Process CmdProcess = new Process();
CmdProcess.StartInfo.FileName = "cmd.exe";
CmdProcess.StartInfo.Arguments = "/C docker images";
CmdProcess.StartInfo.CreateNoWindow = true;
CmdProcess.StartInfo.UseShellExecute = false;
CmdProcess.StartInfo.RedirectStandardOutput = true;
CmdProcess.StartInfo.RedirectStandardError = true;
CmdProcess.Start();

output = CmdProcess.StandardOutput.ReadToEnd();
string error = CmdProcess.StandardError.ReadToEnd();
CmdProcess.WaitForExit();

if (!string.IsNullOrEmpty(error))
{
    MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (!string.IsNullOrEmpty(output))
{
    MessageBox.Show(output, "Docker Image Show", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
    MessageBox.Show("No data", "Docker Image Show", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
coolshrimp
  • 101
  • 5