Reusing Process object and IO redirects in C#

2019-07-22 15:02发布

问题:

I'm using the data ready events of the Process class to get information from the standard output and standard error of a running process.

It works great on the first run, but after calling Stop() then Start() to force a restart of the application, I no longer recieve data. I've tried CancelErrorRead() but no luck there.

I'm considering just re-instantiating the object every time I need to re-run the app, but it seems silly to need to do that.

Any advice on how to re-use a Process object to restart a stopped process?

Relevant code chunks:

Constructor:

   ProcessStartInfo objStartInfo = new ProcessStartInfo();
    objStartInfo.CreateNoWindow = true;
    objStartInfo.RedirectStandardInput = true;
    objStartInfo.RedirectStandardOutput = true;
    objStartInfo.RedirectStandardError = true;
    objStartInfo.UseShellExecute = false;

    objClient = new Process();
    objClient.StartInfo = objStartInfo;

    objClient.EnableRaisingEvents = true;
    objClient.OutputDataReceived   += new DataReceivedEventHandler(read);
    objClient.ErrorDataReceived    += new DataReceivedEventHandler(error);

Start:

    objClient.StartInfo.FileName    = strAppPath;
    objClient.StartInfo.Arguments   = strArgs;
    start();
    objClient.BeginErrorReadLine();
    objClient.BeginOutputReadLine();

Stop:

    objClient.Close();
    objClient.CancelErrorRead();
    objClient.CancelOutputRead();

回答1:

Your Process object is not associated with a process until you call Start() (or use one of the static methods off Process). A stopped/closed process is functionally the same as no process at all. Given that, it's hard to believe there's any overhead to creating a new Process object, when compared to the (relatively enormous) cost of creating processes on Windows. Just create new Process objects as needed.



回答2:

According to msdn you should call BeginOutputReadLine and BeginErrorReadLine to enable asynchronous reads from StandardOutput or StandardError using events.

Have a look at the remarks section on BeginOutputReadLine