Skip to content

Commit

Permalink
Added way to check for updates synchronously and specify the minimum …
Browse files Browse the repository at this point in the history
…recommended version. This resolves #353.
  • Loading branch information
ravibpatel committed Feb 14, 2020
1 parent e0dde7e commit 6b4c87d
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 120 deletions.
268 changes: 152 additions & 116 deletions AutoUpdater.NET/AutoUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,17 @@ public enum Mode
/// <summary>
/// In this mode, it ignores Remind Later and Skip values set previously and hide both buttons.
/// </summary>
[XmlEnum("0")]
Normal,
[XmlEnum("0")] Normal,

/// <summary>
/// In this mode, it won't show close button in addition to Normal mode behaviour.
/// </summary>
[XmlEnum("1")]
Forced,
[XmlEnum("1")] Forced,

/// <summary>
/// In this mode, it will start downloading and applying update without showing standard update dialog in addition to Forced mode behaviour.
/// </summary>
[XmlEnum("2")]
ForcedDownload
[XmlEnum("2")] ForcedDownload
}

/// <summary>
Expand Down Expand Up @@ -154,6 +151,11 @@ public static class AutoUpdater
/// </summary>
public static bool RunUpdateAsAdmin = true;

/// <summary>
/// Set this to true if you want to run update check synchronously.
/// </summary>
public static bool Synchronous = false;

///<summary>
/// Set this to true if you want to ignore previously assigned Remind Later and Skip settings. It will also hide Remind Later and Skip buttons.
/// </summary>
Expand Down Expand Up @@ -217,7 +219,7 @@ public static class AutoUpdater
public static Size? UpdateFormSize = null;

/// <summary>
/// Start checking for new version of application and display dialog to the user if update is available.
/// Start checking for new version of application and display a dialog to the user if update is available.
/// </summary>
/// <param name="myAssembly">Assembly to use for version checking.</param>
public static void Start(Assembly myAssembly = null)
Expand All @@ -226,7 +228,7 @@ public static void Start(Assembly myAssembly = null)
}

/// <summary>
/// Start checking for new version of application via FTP and display dialog to the user if update is available.
/// Start checking for new version of application via FTP and display a dialog to the user if update is available.
/// </summary>
/// <param name="appCast">FTP URL of the xml file that contains information about latest version of the application.</param>
/// <param name="ftpCredentials">Credentials required to connect to FTP server.</param>
Expand All @@ -238,7 +240,7 @@ public static void Start(string appCast, NetworkCredential ftpCredentials, Assem
}

/// <summary>
/// Start checking for new version of application and display dialog to the user if update is available.
/// Start checking for new version of application and display a dialog to the user if update is available.
/// </summary>
/// <param name="appCast">URL of the xml file that contains information about latest version of the application.</param>
/// <param name="myAssembly">Assembly to use for version checking.</param>
Expand Down Expand Up @@ -268,128 +270,60 @@ public static void Start(string appCast, Assembly myAssembly = null)

IsWinFormsApplication = Application.MessageLoop;

var backgroundWorker = new BackgroundWorker();

backgroundWorker.DoWork += BackgroundWorkerDoWork;

backgroundWorker.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted;
Assembly assembly = myAssembly ?? Assembly.GetEntryAssembly();

backgroundWorker.RunWorkerAsync(myAssembly ?? Assembly.GetEntryAssembly());
}
}

private static void BackgroundWorkerOnRunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
{
if (runWorkerCompletedEventArgs.Error != null)
{
if (ReportErrors)
if (Synchronous)
{
if (runWorkerCompletedEventArgs.Error is WebException)
try
{
MessageBox.Show(
Resources.UpdateCheckFailedMessage,
Resources.UpdateCheckFailedCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
var result = CheckUpdate(assembly);

Running = StartUpdate(result);
}
else
catch (Exception exception)
{
MessageBox.Show(runWorkerCompletedEventArgs.Error.ToString(),
runWorkerCompletedEventArgs.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
ShowError(exception);
}
}
}
else
{
if (!runWorkerCompletedEventArgs.Cancelled)
else
{
if (runWorkerCompletedEventArgs.Result is DateTime time)
using (var backgroundWorker = new BackgroundWorker())
{
SetTimer(time);
}
else
{
if (runWorkerCompletedEventArgs.Result is UpdateInfoEventArgs args)
backgroundWorker.DoWork += (sender, args) =>
{
Assembly mainAssembly = args.Argument as Assembly;
args.Result = CheckUpdate(mainAssembly);
};

backgroundWorker.RunWorkerCompleted += (sender, args) =>
{
if (CheckForUpdateEvent != null)
if (args.Error != null)
{
CheckForUpdateEvent(args);
ShowError(args.Error);
}
else
{
if (args.IsUpdateAvailable)
if (!args.Cancelled)
{
if (!IsWinFormsApplication)
{
Application.EnableVisualStyles();
}

if (Mandatory && UpdateMode == Mode.ForcedDownload)
{
DownloadUpdate(args);
Exit();
}
else
if (StartUpdate(args.Result))
{
if (Thread.CurrentThread.GetApartmentState().Equals(ApartmentState.STA))
{
ShowUpdateForm(args);
}
else
{
Thread thread = new Thread(new ThreadStart(delegate
{
ShowUpdateForm(args);
}));
thread.CurrentCulture =
thread.CurrentUICulture = CultureInfo.CurrentCulture;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
return;
}

return;
}

if (ReportErrors)
{
MessageBox.Show(Resources.UpdateUnavailableMessage,
Resources.UpdateUnavailableCaption,
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
}
}

Running = false;
}
/// <summary>
/// Shows standard update dialog.
/// </summary>
public static void ShowUpdateForm(UpdateInfoEventArgs args)
{
using (var updateForm = new UpdateForm(args))
{
if (UpdateFormSize.HasValue)
{
updateForm.Size = UpdateFormSize.Value;
}
Running = false;
};

if (updateForm.ShowDialog().Equals(DialogResult.OK))
{
Exit();
backgroundWorker.RunWorkerAsync(assembly);
}
}
}
}

private static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
private static object CheckUpdate(Assembly mainAssembly)
{
Assembly mainAssembly = e.Argument as Assembly;

var companyAttribute =
(AssemblyCompanyAttribute) GetAttribute(mainAssembly, typeof(AssemblyCompanyAttribute));
string appCompany = companyAttribute != null ? companyAttribute.Company : "";
Expand Down Expand Up @@ -431,15 +365,22 @@ private static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
}
}

if (!Mandatory)
if (string.IsNullOrEmpty(args.CurrentVersion) || string.IsNullOrEmpty(args.DownloadURL))
{
Mandatory = args.Mandatory.Value;
UpdateMode = args.Mandatory.UpdateMode;
throw new MissingFieldException();
}

if (string.IsNullOrEmpty(args.CurrentVersion) || string.IsNullOrEmpty(args.DownloadURL))
args.InstalledVersion = mainAssembly.GetName().Version;
args.IsUpdateAvailable = new Version(args.CurrentVersion) > mainAssembly.GetName().Version;

if (!Mandatory)
{
throw new MissingFieldException();
if (string.IsNullOrEmpty(args.Mandatory.MinimumVersion) ||
args.InstalledVersion < new Version(args.Mandatory.MinimumVersion))
{
Mandatory = args.Mandatory.Value;
UpdateMode = args.Mandatory.UpdateMode;
}
}

if (Mandatory)
Expand All @@ -456,7 +397,7 @@ private static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
var currentVersion = new Version(args.CurrentVersion);
if (currentVersion <= skippedVersion)
return;
return null;

if (currentVersion > skippedVersion)
{
Expand All @@ -472,16 +413,92 @@ private static void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)

if (compareResult < 0)
{
e.Result = remindLaterAt.Value;
return;
return remindLaterAt.Value;
}
}
}

args.InstalledVersion = mainAssembly.GetName().Version;
args.IsUpdateAvailable = new Version(args.CurrentVersion) > mainAssembly.GetName().Version;
return args;
}

private static bool StartUpdate(object result)
{
if (result is DateTime time)
{
SetTimer(time);
}
else
{
if (result is UpdateInfoEventArgs args)
{
if (CheckForUpdateEvent != null)
{
CheckForUpdateEvent(args);
}
else
{
if (args.IsUpdateAvailable)
{
if (!IsWinFormsApplication)
{
Application.EnableVisualStyles();
}

e.Result = args;
if (Mandatory && UpdateMode == Mode.ForcedDownload)
{
DownloadUpdate(args);
Exit();
}
else
{
if (Thread.CurrentThread.GetApartmentState().Equals(ApartmentState.STA))
{
ShowUpdateForm(args);
}
else
{
Thread thread = new Thread(new ThreadStart(delegate { ShowUpdateForm(args); }));
thread.CurrentCulture =
thread.CurrentUICulture = CultureInfo.CurrentCulture;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
}
}

return true;
}

if (ReportErrors)
{
MessageBox.Show(Resources.UpdateUnavailableMessage,
Resources.UpdateUnavailableCaption,
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}

return false;
}

private static void ShowError(Exception exception)
{
if (ReportErrors)
{
if (exception is WebException)
{
MessageBox.Show(
Resources.UpdateCheckFailedMessage,
Resources.UpdateCheckFailedCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show(exception.ToString(),
exception.GetType().ToString(), MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}

/// <summary>
Expand Down Expand Up @@ -616,6 +633,25 @@ public static bool DownloadUpdate(UpdateInfoEventArgs args)
return false;
}

/// <summary>
/// Shows standard update dialog.
/// </summary>
public static void ShowUpdateForm(UpdateInfoEventArgs args)
{
using (var updateForm = new UpdateForm(args))
{
if (UpdateFormSize.HasValue)
{
updateForm.Size = UpdateFormSize.Value;
}

if (updateForm.ShowDialog().Equals(DialogResult.OK))
{
Exit();
}
}
}

internal static MyWebClient GetWebClient(Uri uri, IAuthentication basicAuthentication)
{
MyWebClient webClient = new MyWebClient
Expand Down
6 changes: 6 additions & 0 deletions AutoUpdater.NET/UpdateInfoEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ public class Mandatory
[XmlText]
public bool Value { get; set; }

/// <summary>
/// If this is set and 'Value' property is set to true then it will trigger the mandatory update only when current installed version is less than value of this property.
/// </summary>
[XmlAttribute("minVersion")]
public string MinimumVersion { get; set; }

/// <summary>
/// Mode that should be used for this update.
/// </summary>
Expand Down
Loading

0 comments on commit 6b4c87d

Please sign in to comment.