C# 응용 프로그램에서 생성 된 다른 프로세스의 표준 출력을 부분적으로 읽으십시오.

StackOverflow https://stackoverflow.com/questions/625856

문제

프로세스 클래스를 사용하여 콘솔 애플리케이션을 산란하는 GUI 응용 프로그램이 있습니다.

Process p1 = new Process();
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = "/pn abc.exe /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = true;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);
p1.ErrorDataReceived += new DataReceivedEventHandler(errorreceived);
p1.Start();
tocmd = p1.StandardInput;
p1.BeginOutputReadLine();
p1.BeginErrorReadLine();

이제 콘솔 출력을 비동기로 읽지 만 내부 버퍼에 어느 정도가 채워질 때만 이벤트를 발사하는 것 같습니다. 나는 그것이 다가올 때 데이터를 표시하기를 원합니다. 버퍼에 10 바이트가있는 경우 10 바이트를 표시하십시오. 내 프로그램은 내부적으로 Sleep () 전화를 구현하므로 잠이들 때까지 데이터를 인쇄해야합니다.

어떻게하니?

=============

언급 된 바와 같이 출력은 라인 버퍼링되어 있으며 코드의 다음 변경 사항을 시도했습니다.

p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = pnswitch + " /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = false;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.Start();
tocmd = p1.StandardInput;
MethodInvoker mi = new MethodInvoker(readout);
mi.BeginInvoke(null, p1);

그리고 내부 판독 값

void readout()
    {
        string str;
        while ((str = p1.StandardOutput.ReadLine()) != null)
        {
            richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput), new object[] { str });
            p1.StandardOutput.BaseStream.Flush();
        }
    }

그래서 나는 그것이 각 줄이 쓰여질 때 모니터링되고 그것을 제대로 인쇄한다고 생각합니까? 이것도 작동하지 않았습니다. 거기에 잘못된 것이 있습니까?

도움이 되었습니까?

해결책

수신 된 출력 및 오류 데이터는 라인 버퍼링되며 Newline이 추가 될 때만 발사됩니다.

가장 좋은 방법은 바이트로 바이트를 읽을 수있는 독자를 사용하는 것입니다. 분명히, 이것은 차단이 없어야합니다 :)

다른 팁

이를 달성하려면 리디렉션 된 스트림에서 동기 읽기 작업을 사용해야합니다. 코드는 다음과 같습니다 (MSDN 샘플) :

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
**string output = p.StandardOutput.ReadToEnd();**
p.WaitForExit();

비동기 동작을 달성하려면 일부 스레드를 사용해야합니다.

MSDN 기사 여기

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top