Add progressBar to view progress percentage to a p

2019-02-28 09:37发布

问题:

This is code about my process:

StreamReader outputReader = null;
StreamReader errorReader = null;


       ProcessStartInfo processStartInfo = new ProcessStartInfo(......);
       processStartInfo.ErrorDialog = false;

       //Execute the process
        Process process = new Process();
        process.StartInfo = processStartInfo;
        bool processStarted = process.Start();

                     if (processStarted)
                        {
                        //Get the output stream
                        outputReader = process.StandardOutput;
                        errorReader = process.StandardError;


                        //Display the result
                        string displayText = "Output" + Environment.NewLine + "==============" + Environment.NewLine;
                        displayText += outputReader.ReadToEnd();
                        displayText += Environment.NewLine + Environment.NewLine + "==============" +
                                       Environment.NewLine;
                        displayText += errorReader.ReadToEnd();
                        // txtResult.Text = displayText;
                    }

I need add progressBar to my form to calculate progress percentage to this process, but I dont know how do.

Im using Visual Studio 2012, windows form.

回答1:

Use the process OutputDataReceived event to capture progress. (assuming the process is giving any sort of updates). You could format an initial output to return the total number of increments, and then bump the progress for each output event or actually parse the output data to determine current progress.

In this example the output from the process will set the maximum, and each following step will bump it up.

e.g.

progressBar1.Style = ProgressBarStyle.Continuous;
// for every line written to stdOut, raise a progress event
int result = SpawnProcessSynchronous(fileName, args, out placeholder, false,
    (sender, eventArgs) =>
    {
        if (eventArgs.Data.StartsWith("TotalSteps=")
        {
          progressBar1.Minimum = 0;
          progressBar1.Maximum = Convert.ToInt32(eventArgs.Data.Replace("TotalSteps=",""));
          progressBar1.Value = 0;
        }
        else
        {
          progressBar1.Increment(1);
        }
    });


public static int SpawnProcessSynchronous(string fileName, string args, out string stdOut, bool isVisible, DataReceivedEventHandler OutputDataReceivedDelegate)
{
    int returnValue = 0;
    var processInfo = new ProcessStartInfo();
    stdOut = "";
    processInfo.FileName = fileName;
    processInfo.WorkingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "";
    log.Debug("Set working directory to: {0}", processInfo.WorkingDirectory);

    processInfo.WindowStyle = isVisible ? ProcessWindowStyle.Normal : ProcessWindowStyle.Hidden;
    processInfo.UseShellExecute = false;
    processInfo.RedirectStandardOutput = true;
    processInfo.CreateNoWindow = true;

    processInfo.Arguments = args;
    using (Process process = Process.Start(processInfo))
    {
        if (OutputDataReceivedDelegate != null)
        {
            process.OutputDataReceived += OutputDataReceivedDelegate;
            process.BeginOutputReadLine();
        }
        else
        {
            stdOut = process.StandardOutput.ReadToEnd();
        }
        // do not reverse order of synchronous read to end and WaitForExit or deadlock
        // Wait for the process to end.  
        process.WaitForExit();
        returnValue = process.ExitCode;
    }
    return returnValue;
}


回答2:

A generic Process does not have a built-in mechanism to provide progress notification. You need to figure out some means for the process you are starting to inform of its progress.

If you control that process, you might have it write to Standard Out or Standard Error, and use the

outputReader = process.StandardOutput;
errorReader = process.StandardError;

you have defined to read that progress back into your program. For example, the process could write to Standard Error

10
31
50
99

and your parent process, reading errorReader, could interpret those individual lines as % complete.

Once you have a means of getting the % complete of the child process, you can use a ProgressBar to show that progress.