I have been deploying updates for an application of mine with ClickOnce for a while. While I'm happy to be able to make improvements, I'm a little frustrated with the current progress bar. A little background - I have a XAML window class called "UpdateProgress" that I open when an update is being undertaken for the application. Here's the current code snippet I'm using right now, which does at least notify the user that progress is being made without freezing the application/crashing, but DOES NOT visually update the progress bar:
case UpdateStatuses.UpdateAvailable:
DialogResult dialogResult = System.Windows.Forms.MessageBox.Show("An update is available. Would you like to update the application now?", "Update available", MessageBoxButtons.OKCancel);
if (dialogResult.ToString() == "OK")
{
BackgroundWorker bgUpdate = new BackgroundWorker();
UpdateProgress updateNotify = new UpdateProgress();
bgUpdate.WorkerReportsProgress = true;
bgUpdate.DoWork += (uptSender, uptE) => { UpdateApplication();};
bgUpdate.ProgressChanged += (progSender, progE) => { updateNotify.updateProgress.Value = progE.ProgressPercentage; };
bgUpdate.RunWorkerCompleted += (comSender, comE) => {
updateNotify.Close();
applicationUpdated();
};
updateNotify.Show();
bgUpdate.RunWorkerAsync();
}
break;
Basically, I'm creating a background worker above, which runs the code below:
private static void UpdateApplication()
{
try
{
ApplicationDeployment updateCheck = ApplicationDeployment.CurrentDeployment;
//BackgroundWorker bgWorker = new BackgroundWorker();
//UpdateProgress updateNotify = new UpdateProgress();
//updateCheck.UpdateProgressChanged += (s, e) =>
//{
// updateNotify.updateProgress.Value = e.ProgressPercentage;
//};
//bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(UpdateComponent.noteUpdates);
//bgWorker.RunWorkerAsync();
//updateCheck.UpdateCompleted += (s, e) =>
//{
// updateNotify.Close();
// applicationUpdated();
//};
//updateNotify.Dispatcher.InvokeAsync(() =>
// {
//updateNotify.Show();
updateCheck.Update();
//});
//return null;
}
catch (DeploymentDownloadException dde)
{
System.Windows.MessageBox.Show("Cannot install the latest version of the application. Please check your network connection, or try again later. Error: " + dde);
//return null;
}
}
Quick explanation, currently I'm only creating an "ApplicationDeployment" instance called "updateCheck" and just having it run the update in this thread. What I've tried attempting before, is loading some of the commented code below, only to see the application crash when updating. Turns out, when debugging with a PROD instance of my application, it's due to the following error:
The calling thread cannot access this object because a different thread owns it.
Now, doing some digging, I've seen quite a few good reads about this. From what I understand, part of the problem is that I'm trying to run this code from a static class separated from my MainWindow and other UI classes. I'm doing this to try to keep my code clean and modular, but apparently, that comes with a price. I realize that one can bind the progress bar's progress percentage if it's in the code-behind of, say, the progress bar's window, but what if I'm trying to stick to running this in the static class I speak of instead? I've tried using things like the Dispatcher methods/BeginInvoke(), but unfortunately to end up with the same result.
Can someone give me the best suggestion on how to update the progress of my progress bar in a window with the percentage progress of an ApplicationDeployment instance's update routine?
Thanks a super ton in advance.