Recently, there was a scenario wherein I had to write an application to execute a script (powershell, ruby, shell, any other) on button click in a windows application and show the progress in a progress bar.

This was interesting as I had not tinkered with executing a script with a progress bar. I did some research and found that to run a powershell script, one needs to use Create() method of Powershell class along with the specified parameters. What if its a script other than powershell script?

I used the Process class to achieve this. Using this method I am able to run most of the scripts along with specific parameters. For now I will describe the basic use of the Process class along with the timer to display progress via the progress bar till the process is complete.

I created a simple winform application for this. The application contains a button and the progress bar in a form. On click of the button the process along with its parameters is executed and progress is shown on progress bar.

Below is the code for the button Click event:

private void btnExecProcess_Click(object sender, EventArgs e)
        {
	    // See ProcessStartInfo class on how to pass script parameters as arguments.

            ProcessStartInfo info = new ProcessStartInfo();
            info.UseShellExecute = false;
            info.CreateNoWindow = false;
            info.RedirectStandardError = true;
            info.RedirectStandardOutput = true;
            info.FileName = "calc.exe";
            
            try
            {
		// process is defined at the beginning of the class as a private variable.

                process = Process.Start(info);
                timer1.Start();
            }
            catch (Win32Exception wiex)
            {
                timer1.Stop();
                string err = string.Format("Error: {0}", wiex.Message);
                MessageBox.Show(err, "An error occurred", MessageBoxButtons.OK);
            }
        }

And here is the code for the timer Tick event:

private void timer1_Tick(object sender, EventArgs e)
        {
            if (process != null)
            {
                if (!process.HasExited)
                {
                    if (progressBar1.Value >= progressBar1.Maximum)
                        progressBar1.Value = 1;
                    progressBar1.Value += 1;
                }
                else
                {
                    progressBar1.Value = progressBar1.Maximum;
                    timer1.Stop();
                }
            }
        }

As I am using the button to open a calculator it might not show significant progress in the bar. The value can be increased in multiples like +5 or +10 to see noticeable difference. But it would work better in case you try to run it with actual script (let’s say a .bat file) with parameters so that process takes time to complete.

Do explore Process and ProcessStartInfo properties. Specifically how the error and output of the Process.Start method can be captured and displayed along with conditions on Process.ExitCode values.