Process.start: 출력을 얻는 방법은 무엇입니까?
Mono/에서 외부 명령줄 프로그램을 실행하고 싶습니다.NET 앱.예를 들어, 저는 멘코더를 실행하고 싶습니다.가능합니까?
- 명령줄 셸 출력을 가져오고 내 텍스트 상자에 쓰려면?
- 경과 시간이 있는 진행률 표시줄을 표시하는 숫자 값을 가져오려면 어떻게 해야 합니까?
이 당신의 때을생할을 때.Process
세트 체합집StartInfo
적절한:
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "program.exe",
Arguments = "command line arguments to your executable",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
그런 다음 프로세스를 시작하고 다음을 읽습니다.
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
// do something with line
}
사용할 수 있습니다.int.Parse()
또는int.TryParse()
문자열을 숫자 값으로 변환합니다.읽은 문자열에 잘못된 숫자 문자가 있는 경우 먼저 문자열을 조작해야 할 수 있습니다.
출력을 동기식 또는 비동기식으로 처리할 수 있습니다.
동기식 예제
static void runCommand()
{
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c DIR"; // Note the /c command (*)
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
//* Read the output (or the error)
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
string err = process.StandardError.ReadToEnd();
Console.WriteLine(err);
process.WaitForExit();
}
출력과 오류를 모두 처리하는 것이 좋습니다. 오류는 별도로 처리해야 합니다.
명령의 (서 (*) "는 (으)로 표시됩니다."StartInfo.Arguments
) 다음을 추가해야 합니다./c
지시, 그렇지 않으면 프로세스가 정지합니다.WaitForExit()
.
비동기 예제
static void runCommand()
{
//* Create your Process
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c DIR";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
//* Set your output and error (asynchronous) handlers
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
//* Start process and handlers
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
//* Do your stuff with the output (write to console/log/StringBuilder)
Console.WriteLine(outLine.Data);
}
출력을 사용하여 복잡한 작업을 수행할 필요가 없는 경우 처리기를 직접 인라인에 추가하기만 하면 OutputHandler 메서드를 생략할 수 있습니다.
//* Set your output and error (asynchronous) handlers
process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
좋아요, 오류와 출력을 모두 읽길 원하지만 (나처럼) 다른 답변에 제공된 솔루션 중 하나와 교착 상태에 빠진 사람을 위해, 여기 MSDN 설명을 읽고 구축한 솔루션이 있습니다.StandardOutput
소유물.
답변은 T30의 코드를 기반으로 합니다.
static void runCommand()
{
//* Create your Process
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c DIR";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
//* Set ONLY ONE handler here.
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutputHandler);
//* Start process
process.Start();
//* Read one element asynchronously
process.BeginErrorReadLine();
//* Read the other one synchronously
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
process.WaitForExit();
}
static void ErrorOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
//* Do your stuff with the output (write to console/log/StringBuilder)
Console.WriteLine(outLine.Data);
}
기준.NET 방법은 프로세스의 표준 출력 스트림에서 읽는 것입니다.연결된 MSDN 문서에 예제가 있습니다.마찬가지로 표준 오류에서 읽고 표준 입력에 쓸 수 있습니다.
여기에 설명된 대로 프로세스의 명령줄 셸 출력을 가져올 수 있습니다. http://www.c-sharpcorner.com/UploadFile/edwinlima/SystemDiagnosticProcess12052005035444AM/SystemDiagnosticProcess.aspx
이는 멘코더에 따라 다릅니다.이 상태를 명령줄에 출력하면 예:)
공유 메모리를 사용하여 두 프로세스를 통해 통신할 수 있습니다. 체크아웃.
은 주로 메모리 을 만들입니다.mmf
부모 프로세스에서 "사용" 문을 사용한 다음 종료될 때까지 두 번째 프로세스를 생성하고 결과를 작성하도록 합니다.mmf
사용.BinaryWriter
그리고 나서 그 결과를 읽습니다.mmf
부모 프로세스를 사용하여, 당신은 또한 통과할 수 있습니다.mmf
명령줄 인수 또는 하드 코드를 사용하여 이름을 지정합니다.
부모 프로세스에서 매핑된 파일을 사용할 때 부모 프로세스에서 매핑된 파일이 해제되기 전에 자식 프로세스가 매핑된 파일에 결과를 쓰도록 하십시오.
예: 상위 프로세스
private static void Main(string[] args)
{
using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("memfile", 128))
{
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(512);
}
Console.WriteLine("Starting the child process");
// Command line args are separated by a space
Process p = Process.Start("ChildProcess.exe", "memfile");
Console.WriteLine("Waiting child to die");
p.WaitForExit();
Console.WriteLine("Child died");
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryReader reader = new BinaryReader(stream);
Console.WriteLine("Result:" + reader.ReadInt32());
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
하위 프로세스
private static void Main(string[] args)
{
Console.WriteLine("Child process started");
string mmfName = args[0];
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(mmfName))
{
int readValue;
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryReader reader = new BinaryReader(stream);
Console.WriteLine("child reading: " + (readValue = reader.ReadInt32()));
}
using (MemoryMappedViewStream input = mmf.CreateViewStream())
{
BinaryWriter writer = new BinaryWriter(input);
writer.Write(readValue * 2);
}
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
이 샘플을 사용하려면 내부에 두 개의 프로젝트가 있는 솔루션을 생성한 다음 %childDir%/bin/debug에서 하위 프로세스의 빌드 결과를 가져와 %parentDirectory%/bin/debug로 복사한 다음 상위 프로젝트를 실행합니다.
childDir
그리고.parentDirectory
PC에 있는 당신의 프로젝트의 폴더 이름들은 행운을 빕니다 :)
아래 코드를 사용하여 프로세스 출력을 기록할 수 있습니다.
ProcessStartInfo pinfo = new ProcessStartInfo(item);
pinfo.CreateNoWindow = false;
pinfo.UseShellExecute = true;
pinfo.RedirectStandardOutput = true;
pinfo.RedirectStandardInput = true;
pinfo.RedirectStandardError = true;
pinfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
var p = Process.Start(pinfo);
p.WaitForExit();
Process process = Process.Start(new ProcessStartInfo((item + '>' + item + ".txt"))
{
UseShellExecute = false,
RedirectStandardOutput = true
});
process.WaitForExit();
string output = process.StandardOutput.ReadToEnd();
if (process.ExitCode != 0) {
}
프로세스(예: 배트 파일, 펄 스크립트, 콘솔 프로그램)를 시작하고 표준 출력을 Windows 양식에 표시하는 방법:
processCaller = new ProcessCaller(this);
//processCaller.FileName = @"..\..\hello.bat";
processCaller.FileName = @"commandline.exe";
processCaller.Arguments = "";
processCaller.StdErrReceived += new DataReceivedHandler(writeStreamInfo);
processCaller.StdOutReceived += new DataReceivedHandler(writeStreamInfo);
processCaller.Completed += new EventHandler(processCompletedOrCanceled);
processCaller.Cancelled += new EventHandler(processCompletedOrCanceled);
// processCaller.Failed += no event handler for this one, yet.
this.richTextBox1.Text = "Started function. Please stand by.." + Environment.NewLine;
// the following function starts a process and returns immediately,
// thus allowing the form to stay responsive.
processCaller.Start();
찾을 수 있습니다.ProcessCaller
이 링크에서: 프로세스 시작 및 표준 출력 표시
전화를 걸었을 때 악명 높은 교착 상태 문제에 봉착했습니다.Process.StandardOutput.ReadLine
그리고.Process.StandardOutput.ReadToEnd
.
목표/사용 사례는 간단합니다.프로세스를 시작하고 출력을 리디렉션하면 해당 출력을 캡처하고 를 통해 콘솔에 기록할 수 있습니다.NET Core의ILogger<T>
리디렉션된 출력을 파일 로그에 추가합니다.
기본 제공 비동기 이벤트 핸들러를 사용하는 내 솔루션은 다음과 같습니다.Process.OutputDataReceived
그리고.Process.ErrorDataReceived
.
var p = new Process
{
StartInfo = new ProcessStartInfo(
command.FileName, command.Arguments
)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
}
};
// Asynchronously pushes StdOut and StdErr lines to a thread safe FIFO queue
var logQueue = new ConcurrentQueue<string>();
p.OutputDataReceived += (sender, args) => logQueue.Enqueue(args.Data);
p.ErrorDataReceived += (sender, args) => logQueue.Enqueue(args.Data);
// Start the process and begin streaming StdOut/StdErr
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
// Loop until the process has exited or the CancellationToken is triggered
do
{
var lines = new List<string>();
while (logQueue.TryDequeue(out var log))
{
lines.Add(log);
_logger.LogInformation(log)
}
File.AppendAllLines(_logFilePath, lines);
// Asynchronously sleep for some time
try
{
Task.Delay(5000, stoppingToken).Wait(stoppingToken);
}
catch(OperationCanceledException) {}
} while (!p.HasExited && !stoppingToken.IsCancellationRequested);
win과 linux에서 저에게 효과가 있었던 솔루션은 다음과 같습니다.
// GET api/values
[HttpGet("cifrado/{xml}")]
public ActionResult<IEnumerable<string>> Cifrado(String xml)
{
String nombreXML = DateTime.Now.ToString("ddMMyyyyhhmmss").ToString();
String archivo = "/app/files/"+nombreXML + ".XML";
String comando = " --armor --recipient bibankingprd@bi.com.gt --encrypt " + archivo;
try{
System.IO.File.WriteAllText(archivo, xml);
//String comando = "C:\\GnuPG\\bin\\gpg.exe --recipient licorera@local.com --armor --encrypt C:\\Users\\Administrador\\Documents\\pruebas\\nuevo.xml ";
ProcessStartInfo startInfo = new ProcessStartInfo() {FileName = "/usr/bin/gpg", Arguments = comando };
Process proc = new Process() { StartInfo = startInfo, };
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.Start();
proc.WaitForExit();
Console.WriteLine(proc.StandardOutput.ReadToEnd());
return new string[] { "Archivo encriptado", archivo + " - "+ comando};
}catch (Exception exception){
return new string[] { archivo, "exception: "+exception.ToString() + " - "+ comando };
}
}
언급URL : https://stackoverflow.com/questions/4291912/process-start-how-to-get-the-output
'programing' 카테고리의 다른 글
윈도우즈 cmd stdout 및 stderr을 단일 파일로 리디렉션하는 방법은 무엇입니까? (0) | 2023.05.16 |
---|---|
"위드..."와 동등함C#의 "끝"? (0) | 2023.05.16 |
몽구스 findOne 사용법 (0) | 2023.05.16 |
이전 지점에서 체크아웃할 수 있는 방법이 있습니까? (0) | 2023.05.16 |
기본 UIButton을 프로그래밍 방식으로 만들려면 어떻게 해야 합니까? (0) | 2023.05.16 |