user3342256
user3342256

Reputation: 1290

Updating ShowMessageAsync Progress Value From "External" Method

I have a WPF C# app using the MahApps.Metro UI resources. I'm trying to tie the progress dialog control to a method call from another class and manually increment the progress of the progress bar as the method is stepped through.

I'm having trouble figuring out how I would program "We're at checkpoint 1 of method X - report back 25% complete. Now we're at checkpoint 2 of method X - report back 50% complete."

The method in MainWindow.xaml.cs that initiates the ShowMessageAsync progress bar is shown here:

     private async void installThirdPartyUpdatesButton_Click(object sender, RoutedEventArgs e)
    {
        var app = ((FrameworkElement)sender).DataContext as Tuple<ThirdPartyUpdate.InstalledApplicationFromRegistryScan, ThirdPartyUpdate.ManifestRequiredApplication, ThirdPartyUpdate.RequiredApplicationState>;

        Button ThirdPartyInstallButton = sender as Button;
        ThirdPartyInstallButton.IsEnabled = false;

        var controller = await this.ShowProgressAsync("Please wait...", "Preparing update installation...");
        await Task.Delay(2000);
        controller.SetCancelable(false);

        if (app != null)
        {
            ThirdPartyUpdate.thirdPartyApplicationInstallWorkflow(app);
        }

        controller.SetProgress(.25);
        controller.SetMessage("Closing dependant processes...");
        await Task.Delay(2000);
        controller.SetProgress(.50);
        controller.SetMessage("Uninstalling legacy version...");
        await Task.Delay(2000);
        controller.SetProgress(.75);
        controller.SetMessage("Installing new version...");
        await Task.Delay(2000);
        controller.SetProgress(.100);

        await controller.CloseAsync();
        await this.ShowMessageAsync("Success!", "Update installed successfully.");
    }

The controller.SetProgress entries I have there presently are for illustrative purposes only to show my desired outcome. They render the following:

enter image description here

What I really need is for this method:

ThirdPartyUpdate.thirdPartyApplicationInstallWorkflow(app);

to report back its progress as it hits certain sections of code. Here are the contents of that method in case it helps:

 public static int thirdPartyApplicationInstallWorkflow(Tuple<ThirdPartyUpdate.InstalledApplicationFromRegistryScan, ThirdPartyUpdate.ManifestRequiredApplication, ThirdPartyUpdate.RequiredApplicationState> thirdPartyApp)
    {
        // 1. Close listed process
        // 2. Execute explicit uninstall
        // 3. Execute WMI uninstall
        // 4. Execute install/command          

        writeEvent(EventLogEntryType.Information, "Beginning execution of: " + thirdPartyApp.Item2.Name + " job.", "Third Party Update");

        //Close processes prior to upgrade if needed
        closeProcesses(thirdPartyApp);

        //Execute explicit uninstall if needed
        uninstallExplicit(thirdPartyApp);

        //Execute WMI uninstall if needed
        uninstallWMI(thirdPartyApp);

        //Execute install
        if (!string.IsNullOrEmpty(thirdPartyApp.Item2.InstallString))
        {
            //String cleanup on comma placement so that a few different input styles are valid
            string cleanedstrInstall = thirdPartyApp.Item2.InstallString.Replace(", ", ",").Replace(" ,", ",").Replace(" , ", ",");
            List<string> strInstall = cleanedstrInstall.Split(',').ToList<string>();
            int installExitCode = 0;
            DateTime timeLaunched;
            DateTime timeCompleted;

            foreach (var install in strInstall)
            {
                ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd.exe", "/c " + thirdPartyApp.Item2.InstallString);
                // The following commands are needed to redirect the standard output.
                // This means that it will be redirected to the Process.StandardOutput StreamReader.
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.RedirectStandardError = true;
                procStartInfo.UseShellExecute = false;
                // Do not create the black window.
                procStartInfo.CreateNoWindow = true;
                // Now we create a process, assign its ProcessStartInfo and start it
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo = procStartInfo;
                writeEvent(EventLogEntryType.Information, "Attempting to launch upgrade: " + thirdPartyApp.Item2.InstallString, "Third Party Update");
                timeLaunched = DateTime.UtcNow;
                proc.Start();
                string stderror = proc.StandardError.ReadToEnd();
                proc.WaitForExit();
                timeCompleted = DateTime.UtcNow;
                if (proc.ExitCode == 0 || proc.ExitCode == 3010)
                {
                    writeEvent(EventLogEntryType.Information, "Successfully completed upgrade from: " + thirdPartyApp.Item2.InstallString, "Third Party Update");
                }
            }       
        }
        return 0;
    }

Upvotes: 3

Views: 4354

Answers (1)

user562566
user562566

Reputation:

Just make a delegate to the SetProgress function on the controller.

var controller = await this.ShowProgressAsync("Please wait...", "Progress message");

Define the following delegate somewhere:

public delegate void UpdateProgressFunc(double value);

Change your method thirdPartyApplicationInstallWorkflow to add this delegate as a method parameter:

public static void thirdPartyApplicationInstallWorkflow(App app, UpdateProgressFunc UpdateProgress);

And then from within this function, at the different stages, just call:

UpdateProgress(PERCENT);

Upvotes: 2

Related Questions