방법 : C #에서 명령 줄 실행, STD OUT 결과 가져 오기
C #에서 명령 줄 프로그램을 실행하고 STD OUT 결과를 다시 얻으려면 어떻게해야합니까? 특히 프로그래밍 방식으로 선택된 두 파일에서 DIFF를 실행하고 결과를 텍스트 상자에 쓰고 싶습니다.
// 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 = "YOURBATCHFILE.bat";
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 에서 가져온 것 입니다.
다음은 간단한 샘플입니다.
//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = strCommand;
//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;
pProcess.StartInfo.UseShellExecute = false;
//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;
//Optional
pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;
//Start the process
pProcess.Start();
//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();
//Wait for process to finish
pProcess.WaitForExit();
프로세스 창을 제거하는 데 유용한 다른 매개 변수가 있습니다.
pProcess.StartInfo.CreateNoWindow = true;
원하는 경우 사용자에게 검은 색 콘솔 창을 완전히 숨기는 데 도움이됩니다.
// usage
const string ToolFileName = "example.exe";
string output = RunExternalExe(ToolFileName);
public string RunExternalExe(string filename, string arguments = null)
{
var process = new Process();
process.StartInfo.FileName = filename;
if (!string.IsNullOrEmpty(arguments))
{
process.StartInfo.Arguments = arguments;
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
var stdOutput = new StringBuilder();
process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data); // Use AppendLine rather than Append since args.Data is one line of output, not including the newline character.
string stdError = null;
try
{
process.Start();
process.BeginOutputReadLine();
stdError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
catch (Exception e)
{
throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
}
if (process.ExitCode == 0)
{
return stdOutput.ToString();
}
else
{
var message = new StringBuilder();
if (!string.IsNullOrEmpty(stdError))
{
message.AppendLine(stdError);
}
if (stdOutput.Length != 0)
{
message.AppendLine("Std output:");
message.AppendLine(stdOutput.ToString());
}
throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
}
}
private string Format(string filename, string arguments)
{
return "'" + filename +
((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
"'";
}
System.Diagnostics.ProcessStartInfo psi =
new System.Diagnostics.ProcessStartInfo(@"program_to_call.exe");
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process proc System.Diagnostics.Process.Start(psi);;
System.IO.StreamReader myOutput = proc.StandardOutput;
proc.WaitForExit(2000);
if (proc.HasExited)
{
string output = myOutput.ReadToEnd();
}
이 페이지에서 허용되는 답변은 드문 상황에서 문제가되는 약점을 가지고 있습니다. 프로그램이 규칙, stdout 및 stderr로 쓰는 두 개의 파일 핸들이 있습니다. Ray의 응답과 같은 단일 파일 핸들을 읽고 시작하는 프로그램이 stderr에 충분한 출력을 쓰면 출력 stderr 버퍼 및 블록을 채 웁니다. 그런 다음 두 프로세스가 교착 상태가됩니다. 버퍼 크기는 4K 일 수 있습니다. 이것은 단기 프로그램에서는 극히 드물지만 stderr에 반복적으로 출력되는 장기 실행 프로그램이 있으면 결국 발생합니다. 디버깅 및 추적이 까다 롭습니다.
이것을 처리하는 몇 가지 좋은 방법이 있습니다.
한 가지 방법은 프로그램 대신 cmd.exe를 실행하고 cmd.exe에 대해 / c 인수를 사용하여 cmd.exe에 대한 "2> & 1"인수와 함께 프로그램을 호출하여 stdout과 stderr을 병합하도록 지시하는 것입니다.
var p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
또 다른 방법은 두 핸들을 동시에 읽는 프로그래밍 모델을 사용하는 것입니다.
var p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = @"/c dir \windows"; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = false; p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data); p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data); p.Start(); p.BeginErrorReadLine(); p.BeginOutputReadLine(); p.WaitForExit();
당신은 사용해야합니다 ProcessStartInfo
함께 RedirectStandardOutput
다음 출력 스트림을 읽을 수 - 수있었습니다. ">"를 사용하여 출력을 파일로 리디렉션하고 (OS를 통해)보다 쉽게 파일을 읽을 수 있습니다.
[편집 : 레이가 한 것처럼 : +1]
의존성을 도입하지 않아도 CliWrap은이 를 단순화 할 수 있습니다.
var cli = new Cli("target.exe");
var output = await cli.ExecuteAsync("arguments", "stdin");
var stdout = output.StandardOutput;
이것은 가장 좋은 방법은 아니지만 옵션 일 수 있습니다.
코드에서 실행할 때 "> output.txt"를 추가 한 다음 output.txt 파일을 읽으십시오.
Process 클래스를 사용하여 명령 행 프로그램을 시작하고 작성한 스트림 리더 (문자열 또는 메모리 위치 기반)를 사용하여 Process 인스턴스의 StandardOutput 특성을 설정할 수 있습니다. 프로세스가 완료된 후에는 해당 스트림에서 필요한 모든 차이를 수행 할 수 있습니다.
PC / 서버에서 로컬 ARP 캐시를 쿼리하려는 경우 누군가에게 유용 할 수 있습니다.
List<string[]> results = new List<string[]>();
using (Process p = new Process())
{
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = "/c arp -a";
p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
p.Start();
string line;
while ((line = p.StandardOutput.ReadLine()) != null)
{
if (line != "" && !line.Contains("Interface") && !line.Contains("Physical Address"))
{
var lineArr = line.Trim().Split(' ').Select(n => n).Where(n => !string.IsNullOrEmpty(n)).ToArray();
var arrResult = new string[]
{
lineArr[0],
lineArr[1],
lineArr[2]
};
results.Add(arrResult);
}
}
p.WaitForExit();
}
PublicDomain 공개 소스 코드 에는 ProcessHelper 클래스가 있습니다.
재미있게, 여기에는 버튼 클릭으로 오류보고와 함께 PYTHON 출력을 얻는 완벽한 솔루션이 있습니다. "butPython"이라는 버튼과 "llHello"라는 라벨을 추가하면됩니다.
private void butPython(object sender, EventArgs e)
{
llHello.Text = "Calling Python...";
this.Refresh();
Tuple<String,String> python = GoPython(@"C:\Users\BLAH\Desktop\Code\Python\BLAH.py");
llHello.Text = python.Item1; // Show result.
if (python.Item2.Length > 0) MessageBox.Show("Sorry, there was an error:" + Environment.NewLine + python.Item2);
}
public Tuple<String,String> GoPython(string pythonFile, string moreArgs = "")
{
ProcessStartInfo PSI = new ProcessStartInfo();
PSI.FileName = "py.exe";
PSI.Arguments = string.Format("\"{0}\" {1}", pythonFile, moreArgs);
PSI.CreateNoWindow = true;
PSI.UseShellExecute = false;
PSI.RedirectStandardError = true;
PSI.RedirectStandardOutput = true;
using (Process process = Process.Start(PSI))
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Error(s)!!
string result = reader.ReadToEnd(); // What we want.
return new Tuple<String,String> (result,stderr);
}
}
참고 URL : https://stackoverflow.com/questions/206323/how-to-execute-command-line-in-c-get-std-out-results
'Programing' 카테고리의 다른 글
업데이트 쿼리에서 3 테이블 조인을 수행하는 방법은 무엇입니까? (0) | 2020.02.17 |
---|---|
리스트의 문자열 표현을리스트로 변환 (0) | 2020.02.17 |
플랫폼이 동일하더라도 "잘못된 형식의 프로그램을로드하려고했습니다" (0) | 2020.02.17 |
JavaScript에서 변수가 숫자인지 문자열인지 확인 (0) | 2020.02.17 |
자바 스크립트에서 문자열을 여러 구분 기호로 분리하려면 어떻게합니까? (0) | 2020.02.17 |