2012-06-16 5 views
3

명령 프롬프트 명령을 실행하고 C#의 출력을 읽으려고합니다. 이건 내 코드입니다 :명령 프롬프트 출력을 빈 문자열로 읽는 중

ProcessStartInfo cmdInfo = new ProcessStartInfo("cmd.exe", "/c " + command); 
cmdInfo.CreateNoWindow = true; 
cmdInfo.RedirectStandardOutput = true; 
cmdInfo.UseShellExecute = false; 

Process cmd = new Process(); 
cmd.StartInfo = cmdInfo; 
cmd.Start(); 
string result = cmd.StandardOutput.ReadToEnd(); 
cmd.WaitForExit(); 
cmd.Close(); 
return result; 

그것은 대부분의 시간을 작동하지만, 때로는 결과 = 그게 내가 사용하고 명령이 불가능 할 때 ""(예를 들어, 경로 추가가 성공 또는 실패에 출력을 제공한다). 어떤 아이디어? 프로세스와 ReadToEnd 호출 사이에 경쟁 조건을 생성했는지 궁금합니다.

답변

3

모든 출력이 StandardOutput에 기록되는 것은 아닙니다. 뭔가 잘못되면 많은 응용 프로그램이 StandardError에 쓰기를합니다. 모든 결과를 얻으려면 두 가지를 모두 읽어야합니다.

응용 프로그램이 입력을 차단하지 않는 한 모든 출력을 얻으려면 두 출력 스트림 모두에서 ReadToEnd()을 호출하는 것이 안전해야합니다. 그러나 더 안전한 옵션은 이벤트를 OutputDataReceivedErrorDataReceived 이벤트에 연결하는 것입니다. 로컬 변수를 닫으면 람다 표현식을 붙여 간단하게 만들 수 있습니다 :

var output = new StringBuilder(); 
var error = new StringBuilder(); 

cmd.OutputDataReceived += (o, e) => output.Append(e.Data); 
cmd.ErrorDataReceived += (o, e) => error.Append(e.Data); 

cmd.Start(); 
cmd.BeginOutputReadLine(); 
cmd.BeginErrorReadLine(); 
cmd.WaitForExit(); 
+0

굉장! 이것으로 내 문제는 완전히 고쳐졌습니다. 나는 궁금하지만, 명령이 성공적 일 때, 왜 "OK"입니까? StandardError에 쓰여졌습니까? – akroy

+0

앱은 원하는 출력 스트림을 원하는대로 쓸 수 있습니다. 표준 출력은 종종 파일로 리디렉션되기 때문에 명령 줄 유틸리티는 상태 메시지를 표준 오류에 기록하는 경우가 많습니다. stderr의 "OK"메시지는 여전히 화면에 표시되지만 구문 분석을 원하면 출력에 표시되지 않습니다. –

+0

아, 근본 때문에 OK! 문맥에서 유용하지 않습니다. 모든 것이 의미가 있다고 생각합니다. 고마워요! – akroy