user1021726
user1021726

Reputation: 648

Can't get output from cmd

I'm running this

        string path = string.Format(@"\\{0}\c$\Windows\CCM\Logs", computerName);

        Process process = Process.Start(new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            Arguments = string.Format(@"net use {0} && dir {0}", path),
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        });

        string result = process.StandardOutput.ReadToEnd() + " " + process.StandardError.ReadToEnd();
        process.WaitForExit();

        Console.WriteLine(result);

But nothing is ever written to the console. What am I doing wrong? I've browsed probably every other SO thread regarding this and done a fair amount of Googling but I can't get it to work.

Upvotes: 1

Views: 1469

Answers (5)

jaeger0404
jaeger0404

Reputation: 1

i know this is old, but i wanted to share my solution when i came across this thread. No answer suited my needs. I didn't want read output at end of process. So this is the solution i came up with. The solution solves both fast and slow response and so will always get all the output.

...
process = Process.Start(processInfo);
process.ErrorDataReceived += (sender, eargs) =>
{
    // do something
};
process.OutputDataReceived += (sender, eargs) =>
{
    // do something

};

if (timeout > 0)
{
    // if it is a slow process, read async
    if (!process.WaitForExit(200))
    {
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        if (!process.WaitForExit(timeout))
        {
            // show error
            return;
        }

    } else
    {
        // if it is fast process, need to use "ReadToEnd", because async read will not 
        // caputure output
        var text = process.StandardOutput.ReadToEnd();
        // do something with text

    }
    exitCode = process.ExitCode;
}

Upvotes: 0

rt2800
rt2800

Reputation: 3045

RedirectStandardOutput = true; and RedirectStandardError = true; will redirect respective streams. To capture those streams, you need to handle OutputDataReceived event as follows:

process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.BeginOutputReadLine();

Upvotes: 2

Mårten Wikström
Mårten Wikström

Reputation: 11344

You need to use the /C option to cmd.exe otherwise the child process won't exit.

/C Carries out the command specified by string and then terminates

(Type cmd /? in your command prompt for more information)

Upvotes: 3

Yurii
Yurii

Reputation: 4911

I think you're facing a deadlock as described in the documentation:

A deadlock condition results if the parent process calls p.StandardOutput.ReadToEnd followed by p.StandardError.ReadToEnd and the child process writes enough text to fill its error stream. The parent process would wait indefinitely for the child process to close its StandardOutput stream. The child process would wait indefinitely for the parent to read from the full StandardError stream.

To avoid this you should use asynchronous read operation on one of the streams:

p.BeginOutputReadLine();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();

Courtesy should go to MSDN documentation.

Upvotes: 1

Jehof
Jehof

Reputation: 35554

I´m using the following code to print out the StandardError and StandardOutput of a Process to the Debug/Console

using (StreamReader reader = process.StandardError) {
  string result = reader.ReadToEnd();
  System.Diagnostics.Debug.Write(result);
}

using (StreamReader reader = process.StandardOutput) {
  string result = reader.ReadToEnd();
  System.Diagnostics.Debug.Write(result);
}

process.WaitForExit();

Also i set the following properties on StartInfo

StartInfo.UseShellExecute = false;
StartInfo.ErrorDialog = false;
StartInfo.RedirectStandardOutput = true;
StartInfo.RedirectStandardError = true;

Upvotes: 1

Related Questions