redirecting standard output, event is not raised

2019-09-03 05:17发布

问题:

I'm trying to start a programm and read it's standard output. However the event is never raised. The process i start is running and in console with the same arguments it creates output. Any ideas, what I'm doing wrong?

    public void StartProcess(string Filename, string Arguments)
    {
        currentProcess = new Process();
        currentProcess.StartInfo.FileName = Programm;
        currentProcess.StartInfo.Arguments = Arguments;
        currentProcess.StartInfo.UseShellExecute = false;
        currentProcess.StartInfo.RedirectStandardOutput = true;
        currentProcess.StartInfo.RedirectStandardError = true;
        currentProcess.OutputDataReceived += OutputReceivedEvent;
        currentProcess.EnableRaisingEvents = true;

        string path = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_Result.txt";
        LastResult = path;
        resultfile = File.CreateText(path);

        currentProcess.Start();
        currentProcess.BeginOutputReadLine();
        response.command = Command.ACK;
        SendMessage(response);

    }
    private void OutputReceivedEvent(object sender, DataReceivedEventArgs e)
    {
        resultfile.WriteLine(e.Data);
    }

EDIT: I just discoverd something odd: The process I start is mcast. If I start something else like ping, my code works just fine. So mcast seems to do something funny!

EDIT2: So the code below is working, but only reads blocks of a certain sizes, if less bytes are written to the stream, the even does not occur, neither does .ReadBlock return anything.

EDIT3: So one more update, the problem is, that mcast does not flush it's output stream. I ended up writing my own tool, which is working just fine.

回答1:

Depending on the process you may also need to use currentProcess.ErrorDataReceived and then currentProcess.BeginErrorReadLine() too, as some processes just redirect to one output, and not both. It's worth trying anyway.

So it would look like this:

public void StartProcess(string Filename, string Arguments)
{
    currentProcess = new Process();
    currentProcess.StartInfo.FileName = Programm;
    currentProcess.StartInfo.Arguments = Arguments;
    currentProcess.StartInfo.UseShellExecute = false;
    currentProcess.StartInfo.RedirectStandardOutput = true;
    currentProcess.StartInfo.RedirectStandardError = true;
    currentProcess.OutputDataReceived += OutputReceivedEvent;
    currentProcess.ErrorDataReceived += ErrorReceivedEvent; 

    currentProcess.EnableRaisingEvents = true;

    string path = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + "_Result.txt";
    LastResult = path;
    resultfile = File.CreateText(path);

    currentProcess.Start();
    currentProcess.BeginOutputReadLine();
    currentProcess.BeginErrorReadLine();
    response.command = Command.ACK;
    SendMessage(response);

}
private void OutputReceivedEvent(object sender, DataReceivedEventArgs e)
{
    resultfile.WriteLine(e.Data);
}

/*This second event handler is to prevent a lock occuring from reading two separate streams. 
Not always an issue, but good to protect yourself either way. */
private void ErrorReceivedEvent(object sender, DataReceivedEventArgs e)
{
    resultfile.WriteLine(e.Data);
}