// Copyright 2005 by Omar Al Zabir. All rights are reserved.
//
// If you like this code then feel free to go ahead and use it.
// The only thing I ask is that you don't remove or alter my copyright notice.
//
// Your use of this software is entirely at your own risk. I make no claims or
// warrantees about the reliability or fitness of this code for any particular purpose.
// If you make changes or additions to this code please mark your code as being yours.
//
// website http://www.oazabir.com, email OmarAlZabir@gmail.com, msn oazabir@hotmail.com
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using Microsoft.ApplicationBlocks.Updater;
using Microsoft.ApplicationBlocks.Updater.Activator;
namespace RSSFeeder.Helpers{
/// <summary>
/// Helper class for dealing with the Application Updater Block
/// </summary>
public class UpdaterHelper
{
private int _ManifestDownloaded;
public readonly static UpdaterHelper Instance = new UpdaterHelper();
private int UPDATE_DURATION = 10 * 60 * 1000; // 10 mins
private int STARTUP_DELAY = 20 * 1000; // 60 * 1000; // 1 min
private Form _ParentForm;
private ProgressEventHandler _ProgressHandler;
private bool _IsAbort = false;
private UpdaterHelper()
{
}
public void Start(Form parentForm, ProgressEventHandler progressHandler)
{
this._ParentForm = parentForm;
this._ProgressHandler = progressHandler;
ThreadPool.QueueUserWorkItem( new WaitCallback( CheckAndUpdate ) );
}
public void Stop()
{
this._IsAbort = true;
// Release parent form reference
this._ParentForm = null;
}
private void CheckAndUpdate( object state )
{
try
{
// Get the updater manager
ApplicationUpdaterManager updater = ApplicationUpdaterManager.GetUpdater();
updater.ResumePendingUpdates();
// Subscribe for various events
updater.DownloadStarted +=new DownloadStartedEventHandler(updater_DownloadStarted);
updater.DownloadProgress += new DownloadProgressEventHandler(updater_DownloadProgress);
updater.DownloadCompleted += new DownloadCompletedEventHandler(updater_DownloadCompleted);
updater.DownloadError += new DownloadErrorEventHandler(updater_DownloadError);
updater.ActivationInitializing += new ActivationInitializingEventHandler(updater_ActivationInitializing);
updater.ActivationStarted += new ActivationStartedEventHandler(updater_ActivationStarted);
updater.ActivationInitializationAborted += new ActivationInitializationAbortedEventHandler(updater_ActivationInitializationAborted);
updater.ActivationError += new ActivationErrorEventHandler(updater_ActivationError);
updater.ActivationCompleted +=new ActivationCompletedEventHandler(updater_ActivationCompleted);
// Loop till the updates are available
Manifest[] manifests = null;
while(!this._IsAbort)
{
// Get the default configuration provider for updater block
Microsoft.ApplicationBlocks.Updater.Configuration.UpdaterConfigurationView view =
new Microsoft.ApplicationBlocks.Updater.Configuration.UpdaterConfigurationView();
// Get the default manifest uri in order to add a unique timestamp at its end
// in order to avoid manifest file caching at proxies
Uri manifestUri = view.DefaultManifestUriLocation;
string uri = manifestUri.ToString();
uri += "?" + DateTime.Now.Ticks.ToString();
Thread.Sleep( STARTUP_DELAY ); // Wait, don't try to go for update at startup
manifests = updater.CheckForUpdates(new Uri( uri ));
if(manifests.Length > 0)
{
// Allow all manifests to be applied
foreach(Manifest m in manifests)
{
m.Apply = true;
}
// update the application as per manifest details.
updater.Download( manifests, TimeSpan.FromMinutes(5) );
if(_ManifestDownloaded == manifests.Length)
{
try
{
updater.Activate( manifests );
}
catch( ActivationPausedException x )
{
System.Diagnostics.Debug.WriteLine(x);
return;
}
_ManifestDownloaded = 0;
}
else
{
Thread.Sleep(UPDATE_DURATION);
}
}
else
{
Thread.Sleep(UPDATE_DURATION);
}
}
}
catch(ThreadAbortException ex)
{
System.Diagnostics.Debug.WriteLine(ex);
// Do nothing if the thread is being aborted, as we are explicitly doing it
}
catch( ActivationPausedException ex )
{
System.Diagnostics.Debug.WriteLine(ex);
return;
}
catch(Exception ex)
{
UpdateProgress( ex.Message, 0 );
//MessageBox.Show(this._ParentForm,ex.Message,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
private void updater_DownloadStarted(object sender, DownloadStartedEventArgs e)
{
UpdateProgress("Application Update: Download Started...", 1 );
}
private int _LastProgress = -1;
private void updater_DownloadProgress(object sender, DownloadProgressEventArgs e)
{
if( this._IsAbort ) return;
int progress = (int)(e.BytesTransferred/e.BytesTotal)*100;
if( this._LastProgress != progress )
{
UpdateProgress(string.Format( "Downloading updates: {0}%", progress) , 0);
this._LastProgress = progress;
}
}
private void updater_DownloadCompleted(object sender, ManifestEventArgs e)
{
UpdateProgress("Download Completed, Updating...", 1);
_ManifestDownloaded++;
}
private void updater_DownloadError(object sender, ManifestErrorEventArgs e)
{
UpdateProgress("Error: " + e.Manifest.ManifestId +"\n"+e.Exception.Message, 1);
}
private void updater_ActivationInitializing(object sender, ManifestEventArgs e)
{
UpdateProgress("New version activating...", 1);
}
private void updater_ActivationStarted(object sender, ManifestEventArgs e)
{
UpdateProgress("New version activation started...", 1);
}
private void updater_ActivationInitializationAborted(object sender, ManifestEventArgs e)
{
this._IsAbort = true;
UpdateProgress("New version activation aborted...", 1);
Application.Exit();
}
private void updater_ActivationError(object sender, ManifestErrorEventArgs e)
{
UpdateProgress("Activation Error:" + e.Exception.Message, 1);
}
private void updater_ActivationCompleted(object sender, ActivationCompleteEventArgs e)
{
UpdateProgress("Activation Completed. You have the latest version.", 1);
}
private void UpdateProgress(string displayString, int value )
{
if( null != this._ProgressHandler.Target )
{
this._ProgressHandler( this, new ProgressEventArgs( displayString, value ) );
}
}
}
}
|