user720694
user720694

Reputation: 2075

Process standard output in C# returning empty string

I'm trying to list the supported interfaces on which dumpcap.exe can capture data.

The command i want to run is "dumpcap.exe -D"

On my system, it gives the output as :-

1. \Device\NPF_{1B627AA8-2A1D-4C90-B560-517CF71B33A5} (Intel(R) 825
Network Connection)
2. \Device\NPF_{7ECC4D31-DF17-49AB-960D-628D0580F3C6} (Microsoft)

I'm trying to read the above output by runing the same command from a WPF C# application. I have the following code to do so:-

        Process proc = new Process();

        //set the path to dumpcap.exe (verified by me)
        proc.StartInfo.FileName = "..\\..\\..\\..\\..\\Dumpcap\\dumpcap.exe";

        StringBuilder dumpcapArgs = new StringBuilder();

        dumpcapArgs.Append("-D");

        proc.StartInfo.Arguments = dumpcapArgs.ToString();
        proc.StartInfo.CreateNoWindow = true;
        proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.UseShellExecute = false;

        proc.Start();

        while (!proc.StandardOutput.EndOfStream)
        {
            string line = proc.StandardOutput.ReadLine();
            MessageBox.Show(line);

        }

When i debug, the execution does not go in my while loop at all. The StandardOutput is already at the end of stream. Digging further into StandardOutput base stream class members, i see a lot of System.NotSupportedExceptions in length, position etc.

What is possibly wrong with the above code?

Quick Observation

I tried another sample C# console application with the following code:

        Process proc = new Process();

        proc.StartInfo.FileName = "C:\\Karan\\Dumpcap\\dumpcap.exe";
        proc.StartInfo.Arguments = "-D";
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.Start();

        Console.WriteLine(proc.StandardOutput.ReadToEnd());

        proc.WaitForExit();

This prints the output as expected!

However, if i try to read the standardoutput in a string variable, i get an empty string.

For example, this returns me an empty string:-

       Process proc = new Process();

        proc.StartInfo.FileName = "C:\\Karan\\Dumpcap\\dumpcap.exe";
        proc.StartInfo.Arguments = "-D";
        proc.StartInfo.UseShellExecute = false;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.Start();


        String output = proc.StandardOutput.ReadToEnd();


        proc.WaitForExit();

Upvotes: 4

Views: 7291

Answers (3)

Koen
Koen

Reputation: 2571

Have you set EnableRaisingEvents to true?

I'm not sure if this will do the trick since I usually do the redirecting of the output in a different way:

private Process proc;
private string procOutput = string.Empty;

private void StartProc()
{
    this.procOutput = string.Empty;
    this.proc = new Process();
   ...
    this.proc.StartInfo.UseShellExecute = false;
    this.proc.StartInfo.CreateNoWindow = true;
    this.proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

    this.proc.EnableRaisingEvents = true;
    this.proc.OutputDataReceived += this.ProcOutputDataReceivedHandler;
    this.proc.Exited += this.ProcExitedHandler;

    this.proc.Start();

    this.proc.BeginOutputReadLine();
}

private void ProcOutputDataReceivedHandler(object sendingProcess, DataReceivedEventArgs e)
{
    if (!string.IsNullOrEmpty(e.Data))
    {
         this.procOutput += e.Data;
    }
}

private void ProcExitedHandler(object sender, EventArgs e)
{
    // Check the exitcode for possible errors happened during execution.
    MessageBox.Show(this.procOutput);
}

Upvotes: 3

Gusdor
Gusdor

Reputation: 14334

Try this:

string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();

foreach(var line in output.Split('\r'))
{
    MessageBox.Show(line);
}

Why does this work? Potentially there is nothing in the output stream when you first query EndOfStream. This is a race condition.

I consulted this article before posting. Give it a read http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx

Upvotes: 0

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174309

You never start the process. You should do so using proc.Start();

Length, Position and similar members of Stream are not supported, because the stream representing the standard out of a console application is unknown in length and a forward only stream. So that's normal and not an error in your code.

Upvotes: 2

Related Questions