diff --git a/AutoUpdater.NET/AutoUpdater.cs b/AutoUpdater.NET/AutoUpdater.cs
index 8db20677..f8f15ec7 100644
--- a/AutoUpdater.NET/AutoUpdater.cs
+++ b/AutoUpdater.NET/AutoUpdater.cs
@@ -6,6 +6,7 @@
using System.Net;
using System.Net.Cache;
using System.Reflection;
+using System.Threading;
using System.Windows.Forms;
using System.Xml;
using AutoUpdaterDotNET.Properties;
@@ -39,6 +40,8 @@ public enum RemindLaterFormat
///
public static class AutoUpdater
{
+ private static System.Timers.Timer _remindLaterTimer;
+
internal static String ChangeLogURL;
internal static String DownloadURL;
@@ -53,6 +56,8 @@ public static class AutoUpdater
internal static bool IsWinFormsApplication;
+ internal static bool Running;
+
///
/// Set the Application Title shown in Update dialog. Although AutoUpdater.NET will get it automatically, you can set this property if you like to give custom Title.
///
@@ -67,6 +72,13 @@ public static class AutoUpdater
/// Opens the download url in default browser if true. Very usefull if you have portable application.
///
public static bool OpenDownloadPage;
+
+ ///
+ /// Sets the current culture of the auto update notification window. Set this value if your application supports
+ /// functionalty to change the languge of the application.
+ ///
+ public static CultureInfo CurrentCulture;
+
///
/// If this is true users can see the skip button.
@@ -113,21 +125,12 @@ public static class AutoUpdater
///
/// Start checking for new version of application and display dialog to the user if update is available.
///
- public static void Start()
+ /// Assembly to use for version checking.
+ public static void Start(Assembly myAssembly = null)
{
- Start(AppCastURL);
+ Start(AppCastURL, myAssembly);
}
- ///
- /// A delegate type to handle how to exit the application after update is downloaded.
- ///
- public delegate void ApplicationExitEventHandler();
-
- ///
- /// An event that developers can use to exit the application gracefully.
- ///
- public static event ApplicationExitEventHandler ApplicationExitEvent;
-
///
/// Start checking for new version of application and display dialog to the user if update is available.
///
@@ -135,17 +138,27 @@ public static void Start()
/// Assembly to use for version checking.
public static void Start(String appCast, Assembly myAssembly = null)
{
- AppCastURL = appCast;
+ if (!Running && _remindLaterTimer == null)
+ {
+ Running = true;
+
+ if (CurrentCulture == null)
+ {
+ CurrentCulture = CultureInfo.CurrentCulture;
+ }
- IsWinFormsApplication = Application.MessageLoop;
+ AppCastURL = appCast;
- var backgroundWorker = new BackgroundWorker();
+ IsWinFormsApplication = Application.MessageLoop;
- backgroundWorker.DoWork += BackgroundWorkerDoWork;
+ var backgroundWorker = new BackgroundWorker();
- backgroundWorker.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted;
+ backgroundWorker.DoWork += BackgroundWorkerDoWork;
- backgroundWorker.RunWorkerAsync(myAssembly ?? Assembly.GetEntryAssembly());
+ backgroundWorker.RunWorkerCompleted += BackgroundWorkerOnRunWorkerCompleted;
+
+ backgroundWorker.RunWorkerAsync(myAssembly ?? Assembly.GetEntryAssembly());
+ }
}
private static void BackgroundWorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
@@ -174,8 +187,33 @@ private static void BackgroundWorkerOnRunWorkerCompleted(object sender, RunWorke
{
Application.EnableVisualStyles();
}
- var updateForm = new UpdateForm();
- updateForm.Show();
+ var backgroundworker = new BackgroundWorker();
+ backgroundworker.DoWork += delegate (object o, DoWorkEventArgs eventArgs)
+ {
+ eventArgs.Cancel = true;
+ Thread thread = new Thread(new ThreadStart(delegate
+ {
+ var updateForm = new UpdateForm();
+ if (updateForm.ShowDialog().Equals(DialogResult.OK))
+ {
+ eventArgs.Cancel = false;
+ }
+ }));
+ thread.CurrentCulture = thread.CurrentUICulture = CurrentCulture;
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ thread.Join();
+ };
+ backgroundworker.RunWorkerCompleted +=
+ delegate (object o, RunWorkerCompletedEventArgs eventArgs)
+ {
+ if (!eventArgs.Cancelled)
+ {
+ Exit();
+ }
+ };
+ backgroundworker.RunWorkerAsync();
+ return;
}
else
{
@@ -196,6 +234,7 @@ private static void BackgroundWorkerOnRunWorkerCompleted(object sender, RunWorke
}
}
}
+ Running = false;
}
}
}
@@ -385,39 +424,30 @@ private static string GetURL(Uri baseUri, XmlNode xmlNode)
return temp;
}
- internal static void Exit(Form ownerForm)
+ private static void Exit()
{
- if (ApplicationExitEvent != null)
- {
- ApplicationExitEvent();
- }
- else
+ var currentProcess = Process.GetCurrentProcess();
+ foreach (var process in Process.GetProcessesByName(currentProcess.ProcessName))
{
- var currentProcess = Process.GetCurrentProcess();
- foreach (var process in Process.GetProcessesByName(currentProcess.ProcessName))
+ if (process.Id != currentProcess.Id)
{
- if (process.Id != currentProcess.Id)
- {
- process.Kill();
- }
+ process.Kill();
}
+ }
- ownerForm.Close();
-
- if (IsWinFormsApplication)
- {
- Application.Exit();
- }
- #if NETWPF
- else if (System.Windows.Application.Current != null)
- {
- System.Windows.Application.Current.Shutdown();
- }
- #endif
- else
- {
- Environment.Exit(0);
- }
+ if (IsWinFormsApplication)
+ {
+ Application.Exit();
+ }
+ #if NETWPF
+ else if (System.Windows.Application.Current != null)
+ {
+ System.Windows.Application.Current.Shutdown();
+ }
+ #endif
+ else
+ {
+ Environment.Exit(0);
}
}
@@ -434,16 +464,17 @@ private static Attribute GetAttribute(Assembly assembly, Type attributeType)
internal static void SetTimer(DateTime remindLater)
{
TimeSpan timeSpan = remindLater - DateTime.Now;
- var timer = new System.Timers.Timer
+ _remindLaterTimer = new System.Timers.Timer
{
- Interval = (int) timeSpan.TotalMilliseconds
+ Interval = (int) timeSpan.TotalMilliseconds,
};
- timer.Elapsed += delegate
+ _remindLaterTimer.Elapsed += delegate
{
- timer.Stop();
+ _remindLaterTimer.Stop();
+ _remindLaterTimer = null;
Start();
};
- timer.Start();
+ _remindLaterTimer.Start();
}
///
diff --git a/AutoUpdater.NET/DownloadUpdateDialog.cs b/AutoUpdater.NET/DownloadUpdateDialog.cs
index 5f7a968f..aaab0057 100644
--- a/AutoUpdater.NET/DownloadUpdateDialog.cs
+++ b/AutoUpdater.NET/DownloadUpdateDialog.cs
@@ -81,7 +81,7 @@ private void OnDownloadComplete(object sender, AsyncCompletedEventArgs e)
throw;
}
- AutoUpdater.Exit(this);
+ Close();
}
private static string GetFileName(string url, string httpWebRequestMethod = "HEAD")
diff --git a/AutoUpdater.NET/Resources/ZipExtractor.exe b/AutoUpdater.NET/Resources/ZipExtractor.exe
index 208a6f9a..cc22901c 100644
Binary files a/AutoUpdater.NET/Resources/ZipExtractor.exe and b/AutoUpdater.NET/Resources/ZipExtractor.exe differ
diff --git a/AutoUpdater.NET/UpdateForm.Designer.cs b/AutoUpdater.NET/UpdateForm.Designer.cs
index b8fce756..bd309b8d 100644
--- a/AutoUpdater.NET/UpdateForm.Designer.cs
+++ b/AutoUpdater.NET/UpdateForm.Designer.cs
@@ -64,7 +64,6 @@ private void InitializeComponent()
//
// buttonUpdate
//
- this.buttonUpdate.DialogResult = System.Windows.Forms.DialogResult.OK;
this.buttonUpdate.Image = global::AutoUpdaterDotNET.Properties.Resources.download;
resources.ApplyResources(this.buttonUpdate, "buttonUpdate");
this.buttonUpdate.Name = "buttonUpdate";
@@ -73,7 +72,6 @@ private void InitializeComponent()
//
// buttonRemindLater
//
- this.buttonRemindLater.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonRemindLater.Image = global::AutoUpdaterDotNET.Properties.Resources.clock_go;
resources.ApplyResources(this.buttonRemindLater, "buttonRemindLater");
this.buttonRemindLater.Name = "buttonRemindLater";
@@ -101,7 +99,6 @@ private void InitializeComponent()
this.AcceptButton = this.buttonUpdate;
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.CancelButton = this.buttonRemindLater;
this.Controls.Add(this.pictureBoxIcon);
this.Controls.Add(this.labelReleaseNotes);
this.Controls.Add(this.labelDescription);
@@ -114,6 +111,7 @@ private void InitializeComponent()
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "UpdateForm";
+ this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.UpdateForm_FormClosed);
this.Load += new System.EventHandler(this.UpdateFormLoad);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxIcon)).EndInit();
this.ResumeLayout(false);
diff --git a/AutoUpdater.NET/UpdateForm.cs b/AutoUpdater.NET/UpdateForm.cs
index 9a6e91d5..e9334c51 100644
--- a/AutoUpdater.NET/UpdateForm.cs
+++ b/AutoUpdater.NET/UpdateForm.cs
@@ -61,12 +61,14 @@ private void ButtonUpdateClick(object sender, EventArgs e)
var processStartInfo = new ProcessStartInfo(AutoUpdater.DownloadURL);
Process.Start(processStartInfo);
+
+ DialogResult = DialogResult.OK;
}
else
{
if (AutoUpdater.DownloadUpdate())
{
- Close();
+ DialogResult = DialogResult.OK;
}
}
}
@@ -79,7 +81,6 @@ private void ButtonSkipClick(object sender, EventArgs e)
{
updateKey.SetValue("version", AutoUpdater.CurrentVersion.ToString());
updateKey.SetValue("skip", 1);
- Close();
}
}
}
@@ -97,14 +98,18 @@ private void ButtonRemindLaterClick(object sender, EventArgs e)
AutoUpdater.RemindLaterTimeSpan = remindLaterForm.RemindLaterFormat;
AutoUpdater.RemindLaterAt = remindLaterForm.RemindLaterAt;
}
- if (dialogResult.Equals(DialogResult.Abort))
+ else if (dialogResult.Equals(DialogResult.Abort))
{
if (AutoUpdater.DownloadUpdate())
{
- Close();
+ DialogResult = DialogResult.OK;
}
return;
}
+ else
+ {
+ return;
+ }
}
using (RegistryKey updateKey = Registry.CurrentUser.CreateSubKey(AutoUpdater.RegistryLocation))
@@ -132,7 +137,12 @@ private void ButtonRemindLaterClick(object sender, EventArgs e)
AutoUpdater.SetTimer(remindLaterDateTime);
}
}
- Close();
+ DialogResult = DialogResult.Cancel;
+ }
+
+ private void UpdateForm_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ AutoUpdater.Running = false;
}
}
}
diff --git a/AutoUpdater.NET/UpdateForm.fr.resx b/AutoUpdater.NET/UpdateForm.fr.resx
index ba3cd7b7..92443cc6 100644
--- a/AutoUpdater.NET/UpdateForm.fr.resx
+++ b/AutoUpdater.NET/UpdateForm.fr.resx
@@ -130,7 +130,7 @@
Mettre à jour
- Rappelle plus tard
+ Rappeler plus tard
Passer cette version
diff --git a/AutoUpdaterTestWPF/MainWindow.xaml.cs b/AutoUpdaterTestWPF/MainWindow.xaml.cs
index 1873d701..02e658f1 100644
--- a/AutoUpdaterTestWPF/MainWindow.xaml.cs
+++ b/AutoUpdaterTestWPF/MainWindow.xaml.cs
@@ -1,7 +1,10 @@
-using System.Globalization;
+using System;
+using System.Globalization;
using System.Reflection;
using System.Threading;
+using System.Timers;
using System.Windows;
+using System.Windows.Threading;
using AutoUpdaterDotNET;
namespace AutoUpdaterTestWPF
@@ -17,7 +20,18 @@ public MainWindow()
Assembly assembly = Assembly.GetEntryAssembly();
LabelVersion.Content = $"Current Version : {assembly.GetName().Version}";
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
+ AutoUpdater.LetUserSelectRemindLater = true;
+ AutoUpdater.RemindLaterTimeSpan = RemindLaterFormat.Minutes;
+ AutoUpdater.RemindLaterAt = 1;
AutoUpdater.ReportErrors = true;
+ System.Timers.Timer timer = new System.Timers.Timer {Interval = 2 * 60 * 1000};
+ timer.Elapsed += delegate(object sender, ElapsedEventArgs args)
+ {
+ Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => {
+ AutoUpdater.Start("http://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
+ }));
+ };
+ timer.Start();
}
private void ButtonCheckForUpdate_Click(object sender, RoutedEventArgs e)
diff --git a/README.md b/README.md
index b72a3d0c..31686c60 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ AutoUpdater.NET uses XML file located on a server to get the release information
2.0.0.0
http://rbsoft.org/downloads/AutoUpdaterTest.zip
https://github.com/ravibpatel/AutoUpdater.NET/releases
- false
+ false
````
@@ -50,10 +50,10 @@ Start method of AutoUpdater class takes URL of the XML file you uploaded to serv
## Configuration Options
### Change Language
-You can change of language of the update dialog by adding following line with the above code.
+You can change of language of the update dialog by adding following line with the above code. If you don't do this it will use current culture of your application.
````csharp
-Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("ru");
+AutoUpdater.CurrentCulture = CultureInfo.CreateSpecificCulture("ru");
````
In above example AutoUpdater.NET will show update dialog in russian language.
@@ -104,19 +104,32 @@ AutoUpdater.RemindLaterAt = 2;
In above example when user press Remind Later button of update dialog, It will remind user for update after 2 days.
-## Handling Application exit logic manually
+## Check updates frequently
-If you like to handle Application exit logic yourself then you can use ApplicationExiEvent like below. This is very useful if you like to do something before closing the application.
+You can call Start method inside Timer to check for updates frequently.
+
+###### WinForms
````csharp
-AutoUpdater.ApplicationExitEvent += AutoUpdater_ApplicationExitEvent;
+System.Timers.Timer timer = new System.Timers.Timer {Interval = 2 * 60 * 1000};
+timer.Elapsed += delegate(object sender, ElapsedEventArgs args)
+{
+ AutoUpdater.Start("http://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
+};
+timer.Start();
+````
-private void AutoUpdater_ApplicationExitEvent()
+###### WPF
+
+````csharp
+System.Timers.Timer timer = new System.Timers.Timer {Interval = 2 * 60 * 1000};
+timer.Elapsed += delegate(object sender, ElapsedEventArgs args)
{
- Text = @"Closing application...";
- Thread.Sleep(5000);
- Application.Exit();
-}
+ Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => {
+ AutoUpdater.Start("http://rbsoft.org/updates/AutoUpdaterTestWPF.xml");
+ }));
+};
+timer.Start();
````
## Handling updates manually