Get Values from Process StandardOutput

I am attempting to get output to show the currently open documents on my machine, but it comes back NULL no matter what.

StringCollection values = new StringCollection();
var proc = new Process
{
     StartInfo = new ProcessStartInfo
     {
          FileName = "openfiles.exe",
          Arguments = "/query /FO CSV /v",
          UseShellExecute = false,
          RedirectStandardOutput = true,
          CreateNoWindow = true
     }
};
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
     string line = proc.StandardOutput.ReadLine();
     values.Add(line);
}
foreach (string sline in values)
MessageBox.Show(sline);

Edit:

During further review I see that I am getting an exception issue. During my diag run I get the following: Proc.BasePriority thre an exception of type System.InvalidOperationException

Edit:

Attempted to pull code as:

string val = proc.StandardOutput.ReadToEnd();
MessageBox.Show(val);

Also a NULL value on return, and Proc still had errors even after proc.start();.


You have to read both the standard output and standard error streams. This is because you can't read them both from the same thread.

To achieve this you have to use the eventhandlers that will be called on a separate thread.

Compile the code as anycpu as openfiles comes in a 32-bit and 64-bit variant. It might not find the executable if there is an architecture mismatch.

The lines that are read from the error stream are prepended with ! > so they stand out in the output.

    StringCollection values = new StringCollection();
    var proc = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "openfiles.exe",
            Arguments = "/query /FO CSV /v",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = false
        }
    };
    proc.Start();

    proc.OutputDataReceived += (s,e) => {
        lock (values)
        {
            values.Add(e.Data);
        }
    };
    proc.ErrorDataReceived += (s,e) => {
        lock (values)
        {
            values.Add("! > " + e.Data);
        }
    };

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
    foreach (string sline in values)
        MessageBox.Show(sline);