using System; using System.Diagnostics; using System.IO; using System.Threading; using System.Windows.Forms; namespace CheckForUpdateTest { public partial class Form1 : Form { private void SaveFilePathToDelete(string filePath) { // save the filePath somewhere (config file/registry) // so it can be accessed next time application in run } private string GetPathToDelete() { //return a file path saved by SaveFilePathToDelete return null; } private bool CheckForNewVersion() { // check if the new version if available // use this.ShouldStop while checking so the thread // can be interrupted: // if this.ShouldStop() throw new ThreadInterruptedException(""); return true; } private string DownloadInstaller() { /* Download the installer Save it to disk in case of an error - throw exception use this.ShouldStop while checking so the thread can be interrupted: if this.ShouldStop() throw new ThreadInterruptedException(""); */ return Path.Combine(Path.GetTempPath(), "OurApp.msi"); } private Thread m_WorkerThread; readonly ManualResetEvent stopThread; readonly ManualResetEvent threadStopped; public Form1() { InitializeComponent(); // delete the installer string filePath = this.GetPathToDelete(); if (!string.IsNullOrEmpty(filePath)) { try { File.Delete(filePath); this.SaveFilePathToDelete(null); } catch { } } this.stopThread = new ManualResetEvent(false); this.threadStopped = new ManualResetEvent(false); } private void checkForUpdatesButton_Click(object sender, EventArgs e) { // check if the thread is currently running if ((this.m_WorkerThread != null) && (this.m_WorkerThread.IsAlive)) return; // run the WorkerThread method in a new thread this.m_WorkerThread = new Thread(this.WorkerThread); this.stopThread.Reset(); this.threadStopped.Reset(); this.m_WorkerThread.Start(); } // delegates called by m_WorkerThread private delegate bool DelegateAfterChecking(bool foundNewVersion); private delegate void DelegateAfterDownloading(bool downloaded, string filePath); private void WorkerThread() { // this method is executed in m_WorkerThread try { // check if a new version is available bool newVersion = this.CheckForNewVersion(); // inform about the status // ask the user if he wants us to download the newest version bool download = (bool)this.Invoke(new DelegateAfterChecking(this.OnCheckingFinished), new Object[] { newVersion }); if (!download) return; // download the installer string filePath; bool downloadSuccess = true; try { filePath = this.DownloadInstaller(); } catch { filePath = null; downloadSuccess = false; } // inform the user about the status // execute the installer this.BeginInvoke(new DelegateAfterDownloading(this.OnDownloadFinished), new Object[] { downloadSuccess, filePath }); } catch (ThreadInterruptedException) { } } private bool OnCheckingFinished(bool foundNewVersion) { // called after checking for new version is finished // returns true if the user wants to download the newest version if (!foundNewVersion) { MessageBox.Show("No updates available", "Check for update"); return false; } return DialogResult.Yes == MessageBox.Show("Download new version?", "Check for update", MessageBoxButtons.YesNo, MessageBoxIcon.Question); } private void OnDownloadFinished(bool downloaded, string filePath) { // called after the new version has been downloaded // installs it if (!downloaded) MessageBox.Show("download error", "Downloading new version"); else if (DialogResult.Yes == MessageBox.Show("Install new version?", "Check for update", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { try { Process.Start(filePath); this.SaveFilePathToDelete(filePath); Application.Exit(); } catch (Exception) { try { File.Delete(filePath); }catch { } MessageBox.Show("Error executing the installer"); } } } private bool ShouldStop() { // called by thread // returns true if the thread should interrupt its work if (this.stopThread.WaitOne(0, true)) { this.threadStopped.Set(); return true; } return false; } public void StopThread() { // waits until m_WorkerThread finishes if ((this.m_WorkerThread != null) && this.m_WorkerThread.IsAlive) { this.stopThread.Set(); while (this.m_WorkerThread.IsAlive) { if (WaitHandle.WaitAll( (new ManualResetEvent[] { this.threadStopped }), 100, true)) { break; } Application.DoEvents(); } } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // we stop the background thread before closing the application this.StopThread(); } } class ThreadInterruptedException : ApplicationException { /* * Our custom exception. Thrown to interrupt the thread execution */ public ThreadInterruptedException(String problem) : base(problem) { } } }