0

I am trying to run a command in cmd.exe, and redirect the output to a textfile. I have verified that the command is being executed, but when I call StandardOutput.ReadToEnd() or StandardError.ReadToEnd(), an empty string is returned instead of the text output from the command. Am I missing something?

    ProcessStartInfo PSI = new ProcessStartInfo("cmd.exe", command);

    PSI.UseShellExecute = false;
    PSI.CreateNoWindow = true;
    PSI.RedirectStandardInput = true;
    PSI.RedirectStandardOutput = true;
    PSI.RedirectStandardError = true;
    PSI.Arguments = "/c";

    var proc = Process.Start(PSI);
    proc.WaitForExit();

    string output = proc.StandardOutput.ReadToEnd();
    Console.WriteLine(output);

    string errors = proc.StandardError.ReadToEnd();
    Console.WriteLine(errors);
Flopdong
  • 259
  • 1
  • 3
  • 15
  • 1
    I was about to post an answer, but it's closed for an invalid main cause, unfortunately. The arguments specified in the constructor get overwritten by the `Arguments` property. So what you're actually calling is `cmd.exe /c` instead of `cmd.exe {command}`, which doesn't output anything. Ref: https://github.com/Microsoft/referencesource/blob/master/System/services/monitoring/system/diagnosticts/ProcessStartInfo.cs#L89 and https://github.com/Microsoft/referencesource/blob/master/System/services/monitoring/system/diagnosticts/ProcessStartInfo.cs#L135 – Caramiriel Apr 17 '18 at 19:40

1 Answers1

1

I'm pretty sure using ReadToEnd doesn't work if you're also capturing error output at the same time. You'll need to use proc.BeginOutputReadLine() instead (and proc.BeginErrorReadLine() for the error output).

However, those methods are asynchronous, so you'll need to use event handlers to actually get the output.

PSI.EnableRaisingEvents = true;
proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(OutputReceivedHandler);
proc.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(ErrorReceivedHandler);

The handlers have the output/error data stored in the event argument's Data property.

private void OutputReceivedHandler(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data);
}

private void ErrorReceivedHandler(object sender, ErrorReceivedEventArgs e)
{
    Console.WriteLine(e.Data);
}

Since this is all asynchronous, you'll want to ditch the WaitForExit call, as that will block unnecessarily. If you do want the call to block, you can use WaitForExit, but refer to the answer that user Greg linked in the comments for an implementation that won't result in a buffer overflow.

pushasha
  • 769
  • 7
  • 15
  • 1
    This question might be a solid reference for him that speaks about the above. https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why?lq=1 – Greg Apr 17 '18 at 19:16
  • 2
    @Greg then mark the question as duplicate instead of posting a poor answer – Eser Apr 17 '18 at 19:19
  • @Eser I'm in slow motion, brain spaced. – Greg Apr 17 '18 at 19:21
  • @Eser The question is not a duplicate, but the answers are somewhat similar. I'll edit my answer and add a bit about Greg's comment in. – pushasha Apr 17 '18 at 19:22
  • 1
    @pushasha Of course *executing a process and reading the outputs* has been answered millions of times. *"asinus asinum fricat"* – Eser Apr 17 '18 at 19:24
  • @Eser I get where you're coming from, but I'm not sure that's how things are normally handled on SO. For instance, "Why is my TextBox empty after setting the text?" is usually not marked as a duplicate of "How do I set the text of a TextBox?"... or at least that's the impression I've received while being a part of the community. Not flagging questions like this will help people who believe they know how to accomplish a task (and therefore won't be searching the general "how to" questions), but are encountering specific implementation issues and are searching for answers. – pushasha Apr 17 '18 at 19:33
  • @pushasha I am not not here 24/7 and I sometimes miss those type of questions :) At the end , if there is a similar answer here, it is duplicate and the question is lacking a research effort. SO is not a place to encourage laziness. – Eser Apr 17 '18 at 19:35
  • 1
    @pushasha BTW: I upvoted your answer – Eser Apr 17 '18 at 19:39
  • @Eser Appreciated. But yeah, I guess we can agree to disagree on our SO philosophy. Again, I definitely understand where you're coming from, though. Cheers :) – pushasha Apr 17 '18 at 19:39
  • @pushasha, `I definitely understand where you're coming from` But I definitely not undertand what you mean... – Eser Apr 17 '18 at 19:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169197/discussion-between-pushasha-and-eser). – pushasha Apr 17 '18 at 19:43