Fly*_*wat 133 .net c# process spawning
我需要生成一个作为控制台应用程序的子进程,并捕获其输出.
我为方法编写了以下代码:
string retMessage = String.Empty;
ProcessStartInfo startInfo = new ProcessStartInfo();
Process p = new Process();
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.UseShellExecute = false;
startInfo.Arguments = command;
startInfo.FileName = exec;
p.StartInfo = startInfo;
p.Start();
p.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
using (StreamReader output = p.StandardOutput)
{
retMessage = output.ReadToEnd();
}
}
);
p.WaitForExit();
return retMessage;
Run Code Online (Sandbox Code Playgroud)
但是,这不会返回任何内容.我不相信该OutputDataReceived事件被回调,或者该WaitForExit()命令可能阻塞该线程,因此它永远不会回调.
有什么建议?
编辑:看起来我在回调中努力了.这样做:
return p.StandardOutput.ReadToEnd();
Run Code Online (Sandbox Code Playgroud)
似乎工作正常.
Jud*_*ngo 153
这是我已经验证可以使用的代码.我用它来产生MSBuild并监听它的输出:
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += (sender, args) => Console.WriteLine("received output: {0}", args.Data);
process.Start();
process.BeginOutputReadLine();
Run Code Online (Sandbox Code Playgroud)
Uma*_*aja 35
我刚尝试了这件事,以下内容对我有用:
StringBuilder outputBuilder;
ProcessStartInfo processStartInfo;
Process process;
outputBuilder = new StringBuilder();
processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.UseShellExecute = false;
processStartInfo.Arguments = "<insert command line arguments here>";
processStartInfo.FileName = "<insert tool path here>";
process = new Process();
process.StartInfo = processStartInfo;
// enable raising events because Process does not raise events by default
process.EnableRaisingEvents = true;
// attach the event handler for OutputDataReceived before starting the process
process.OutputDataReceived += new DataReceivedEventHandler
(
delegate(object sender, DataReceivedEventArgs e)
{
// append the new data to the data already read-in
outputBuilder.Append(e.Data);
}
);
// start the process
// then begin asynchronously reading the output
// then wait for the process to exit
// then cancel asynchronously reading the output
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
process.CancelOutputRead();
// use the output
string output = outputBuilder.ToString();
Run Code Online (Sandbox Code Playgroud)
Rob*_*ler 22
我需要捕获stdout和stderr并且如果进程在预期时没有退出则超时.我想出了这个:
Process process = new Process();
StringBuilder outputStringBuilder = new StringBuilder();
try
{
process.StartInfo.FileName = exeFileName;
process.StartInfo.WorkingDirectory = args.ExeDirectory;
process.StartInfo.Arguments = args;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.EnableRaisingEvents = false;
process.OutputDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);
process.ErrorDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
var processExited = process.WaitForExit(PROCESS_TIMEOUT);
if (processExited == false) // we timed out...
{
process.Kill();
throw new Exception("ERROR: Process took too long to finish");
}
else if (process.ExitCode != 0)
{
var output = outputStringBuilder.ToString();
var prefixMessage = "";
throw new Exception("Process exited with non-zero exit code of: " + process.ExitCode + Environment.NewLine +
"Output from process: " + outputStringBuilder.ToString());
}
}
finally
{
process.Close();
}
Run Code Online (Sandbox Code Playgroud)
我正在将stdout和stderr连接到相同的字符串中,但如果需要,可以将它分开.它使用事件,所以它应该处理它们(我相信).我已成功运行,并将很快进行批量测试.
Sam*_*Sam 21
这里有一些完整而简单的代码.我使用它时工作正常.
var processStartInfo = new ProcessStartInfo
{
FileName = @"C:\SomeProgram",
Arguments = "Arguments",
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(processStartInfo);
var output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
Run Code Online (Sandbox Code Playgroud)
请注意,这仅捕获标准输出 ; 它没有捕获标准错误.如果您想要两者,请对每个流使用此技术.
Jar*_*Par 20
看起来你的两条线路无序.您在设置事件处理程序以捕获输出之前启动该过程.在添加事件处理程序之前,该过程可能刚刚完成.
像这样切换线.
p.OutputDataReceived += ...
p.Start();
Run Code Online (Sandbox Code Playgroud)
重定向流是异步的,并且在进程终止后可能会继续。Umar 提到要在进程终止后取消process.CancelOutputRead()。然而,这有可能丢失数据。
这对我来说工作可靠:
process.WaitForExit(...);
...
while (process.StandardOutput.EndOfStream == false)
{
Thread.Sleep(100);
}
Run Code Online (Sandbox Code Playgroud)
我没有尝试过这种方法,但我喜欢 Sly 的建议:
if (process.WaitForExit(timeout))
{
process.WaitForExit();
}
Run Code Online (Sandbox Code Playgroud)