C#ProcessStartInfo.Start - 读输出,但有超时ProcessStartInfo、Start

2023-09-02 01:56:55 作者:精神失常、适合你

如果要启动另一个进程,并等待(带超时)才能完成,你可以使用以下(从MSDN)。

If you want to start another process and wait (with time out) to finish you can use the following (from MSDN).

//Set a time-out value.
int timeOut=5000;
//Get path to system folder.
string sysFolder= 
    Environment.GetFolderPath(Environment.SpecialFolder.System);
//Create a new process info structure.
ProcessStartInfo pInfo = new ProcessStartInfo();
//Set file name to open.
pInfo.FileName = sysFolder + @"eula.txt";
//Start the process.
Process p = Process.Start(pInfo);
//Wait for window to finish loading.
p.WaitForInputIdle();
//Wait for the process to exit or time out.
p.WaitForExit(timeOut);
//Check to see if the process is still running.
if (p.HasExited == false)
    //Process is still running.
    //Test to see if the process is hung up.
    if (p.Responding)
        //Process was responding; close the main window.
        p.CloseMainWindow();
    else
        //Process was not responding; force the process to close.
        p.Kill();

MessageBox.Show("Code continuing...");

如果要启动另一个进程,并读出它的输出,那么你可以使用following (从SO)

If you want to start another process and read its output then you can use the following pattern (from SO)

// 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();

您如何将二者结合起来阅读所有的输入,而不是陷在僵局,有一个超时,如果正在运行的进程都被打乱?

How can you combine the two to read all input, not get stuck in deadlock and have a timeout if the running process goes awry?

推荐答案

如果输出缓冲区充满了更多的4KB的数据,这种技术将挂起。一个更简单的方法就是注册时的东西被写入到输出流被通知与会代表。 I've已经在另一篇文章之前,建议此方法:

This technique will hang if the output buffer is filled with more that 4KB of data. A more foolproof method is to register delegates to be notified when something is written to the output stream. I've already suggested this method before in another post:

ProcessStartInfo processInfo = new ProcessStartInfo("Write500Lines.exe");
processInfo.ErrorDialog = false;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;

Process proc = Process.Start(processInfo);

// You can pass any delegate that matches the appropriate 
// signature to ErrorDataReceived and OutputDataReceived
proc.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null) Trace.WriteLine(errorLine.Data); };
proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) Trace.WriteLine(outputLine.Data); };
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

proc.WaitForExit();