c# ProcessStartInfo.Start - reading output but with a timeout

后端 未结 6 1521
小鲜肉
小鲜肉 2020-12-08 23:53

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;
//Ge         


        
相关标签:
6条回答
  • 2020-12-09 00:33
    void OpenWithStartInfo()
    {
        ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe", "Default2.aspx");
        startInfo.WindowStyle = ProcessWindowStyle.Minimized;
        Process p = Process.Start(startInfo);
        p.WaitForInputIdle();  
        //p.WaitForExit(2);
        p.Kill();
    }
    
    0 讨论(0)
  • 2020-12-09 00:34

    you can try modifying the first method to something like this

    Process p = Process.Start(pInfo);
    string output = string.Empty;
    Thread t = new Thread(() =>  output = p.StandardOutput.ReadToEnd() );
    t.Start();
    //Wait for window to finish loading.
    p.WaitForInputIdle();
    //Wait for the process to exit or time out.
    p.WaitForExit(timeOut);
    
    0 讨论(0)
  • 2020-12-09 00:42

    Just add everything from the first example below the WaitForExit() call to the second example.

    0 讨论(0)
  • 2020-12-09 00:49

    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();
    
    0 讨论(0)
  • 2020-12-09 00:50

    You don't have to combine the two - the Process class has an event that fires when output is sent to the StandardOutput - OutputDataReceived.

    If you subscribe to the event, you will be able to read output as it arrives and in your main program loop you can still timeout.

    0 讨论(0)
  • 2020-12-09 00:51

    You could also use the APM, like this:

    Define a delegate for the ReadToEnd call:

    private delegate string ReadToEndDelegate();
    

    Then use the delegate to call the method like this:

    ReadToEndDelegate asyncCall = reader.ReadToEnd;
    IAsyncResult asyncResult = asyncCall.BeginInvoke(null, null);
    asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(10));
    asyncCall.EndInvoke(asyncResult);
    

    EDIT: Error handling removed for clarity.

    0 讨论(0)
提交回复
热议问题