/// <summary> /// Occurs when the engine's background thread runs /// </summary> /// <param name="sender"></param> /// <param name="ea"></param> protected virtual void OnThreadRun(object sender, BackgroundThreadStartEventArgs threadStartEventArgs) { bool downloaded = false; bool installed = false; bool finalized = false; AutoUpdateDownloadDescriptor recommendedUpdateDescriptor = null; try { /* * Raise the AutoUpdateProcessStarted event * */ AutoUpdateManagerEventArgs startedArgs = new AutoUpdateManagerEventArgs(this, null); this.OnAutoUpdateProcessStarted(this, startedArgs); #region Step 1. QueryForLatestVersion /* * Raise the BeforeQueryForLatestVersion event * */ AutoUpdateManagerCancelEventArgs beforeQueryArgs = new AutoUpdateManagerCancelEventArgs(this, startedArgs.ProgressViewer, false); this.OnBeforeQueryForLatestVersion(this, beforeQueryArgs); // create an array list to hold all of the available updates ArrayList listOfAvailableDownloads = new ArrayList(); // use the downloaders to check for downloads foreach(AutoUpdateDownloader downloader in _downloaders) { try { // query the latest update available for the specified product AutoUpdateDownloadDescriptor updateAvailable; // if the downloader finds an update is available if (downloader.QueryLatestVersion(beforeQueryArgs.ProgressViewer, _options, _productToUpdate, out updateAvailable)) // add it to the list of downloads available listOfAvailableDownloads.Add(updateAvailable); } catch(ThreadAbortException ex) { throw new Exception(ex.Message, ex); } catch(Exception ex) { Debug.WriteLine(ex); } } // create a simple array of the updates that are available for download AutoUpdateDownloadDescriptor[] availableDownloads = listOfAvailableDownloads.ToArray(typeof(AutoUpdateDownloadDescriptor)) as AutoUpdateDownloadDescriptor[]; // sort and select the download that contains the newest version recommendedUpdateDescriptor = this.SelectTheDownloadWithTheNewestUpdate(availableDownloads); /* * Raise the AfterQueryForLatestVersion event * */ AutoUpdateManagerWithDownloadDescriptorEventArgs afterQueryArgs = new AutoUpdateManagerWithDownloadDescriptorEventArgs(this, beforeQueryArgs.ProgressViewer, recommendedUpdateDescriptor); this.OnAfterQueryForLatestVersion(this, afterQueryArgs); // if the manager could not find a suitable recomendation for downloading, we're done if (recommendedUpdateDescriptor == null) { /* * Raise the NoLaterVersionAvailable event * */ this.OnNoLaterVersionAvailable(this, new AutoUpdateManagerEventArgs(this, afterQueryArgs.ProgressViewer)); return; } // or if the product to update is newer or equal to the version of the recommended update picked for downloading if (_productToUpdate.Version >= recommendedUpdateDescriptor.Manifest.Product.Version) { /* * Raise the NoLaterVersionAvailable event * */ this.OnNoLaterVersionAvailable(this, new AutoUpdateManagerEventArgs(this, afterQueryArgs.ProgressViewer)); return; } #endregion #region Step 2. Download /* * Create the path including the filename where the .Update file will be downloaded to locally * (ex: "C:\Program Files\Razor\1.0.0.0.update") * */ recommendedUpdateDescriptor.DownloadedPath = Path.Combine(_options.DownloadPath, Path.GetFileName(recommendedUpdateDescriptor.Manifest.UrlOfUpdate)); /* * Raise the BeforeDownload event * */ AutoUpdateManagerWithDownloadDescriptorCancelEventArgs beforeDownloadArgs = new AutoUpdateManagerWithDownloadDescriptorCancelEventArgs(this, afterQueryArgs.ProgressViewer, recommendedUpdateDescriptor, false); this.OnBeforeDownload(this, beforeDownloadArgs); // bail if the download was cancelled if (beforeDownloadArgs.Cancel) return; // use the downloader that found the update to download it // the update may be available via some proprietary communications channel (http, ftp, or Unc paths) downloaded = recommendedUpdateDescriptor.Downloader.Download(beforeDownloadArgs.ProgressViewer, recommendedUpdateDescriptor); /* * Raise the AfterDownload event * */ AutoUpdateManagerWithDownloadDescriptorEventArgs afterDownloadArgs = new AutoUpdateManagerWithDownloadDescriptorEventArgs(this, beforeDownloadArgs.ProgressViewer, recommendedUpdateDescriptor); afterDownloadArgs.OperationStatus = downloaded; this.OnAfterDownload(this, afterDownloadArgs); // if the download failed bail out if (!downloaded) return; #endregion #region Step 3. Install /* * Raise the BeforeInstall event * */ AutoUpdateManagerWithDownloadDescriptorCancelEventArgs beforeInstallArgs = new AutoUpdateManagerWithDownloadDescriptorCancelEventArgs(this, afterDownloadArgs.ProgressViewer, recommendedUpdateDescriptor, false); this.OnBeforeInstall(this, beforeInstallArgs); // if the installation was not cancelled if (!beforeInstallArgs.Cancel) { // install the update installed = this.InstallUpdate(beforeInstallArgs.ProgressViewer, recommendedUpdateDescriptor); // if the update was installed, now is the time to finalize the installation if (installed) { // all the downloader to finalize the install, there may be things to do after the installation is complete // depending upon the source of the download, and again since it's plugable only the downloader will know how to deal with it // and by default it will just delete the downloaded .update file finalized = recommendedUpdateDescriptor.Downloader.FinalizeInstallation(beforeInstallArgs.ProgressViewer, recommendedUpdateDescriptor); } } /* * Raise the AfterInstall event * */ AutoUpdateManagerWithDownloadDescriptorEventArgs afterInstallArgs = new AutoUpdateManagerWithDownloadDescriptorEventArgs(this, beforeInstallArgs.ProgressViewer, recommendedUpdateDescriptor); afterInstallArgs.OperationStatus = installed && finalized; this.OnAfterInstall(this, afterInstallArgs); #endregion #region Step 4. Update Alternate Path /* * Raise the X event * */ AutoUpdateManagerWithDownloadDescriptorCancelEventArgs beforeUpdateAltPathArgs = new AutoUpdateManagerWithDownloadDescriptorCancelEventArgs(this, afterInstallArgs.ProgressViewer, recommendedUpdateDescriptor, false); this.OnBeforeUpdateAlternatePath(this, beforeUpdateAltPathArgs); if (!beforeUpdateAltPathArgs.Cancel) { // copy the manifest & the update there this.AdjustUrlOfUpdateInManifest(_options, recommendedUpdateDescriptor); this.CreateCopyOfManifestInAlternatePath(beforeUpdateAltPathArgs.ProgressViewer, recommendedUpdateDescriptor); this.CreateCopyOfUpdateInAlternatePath(beforeUpdateAltPathArgs.ProgressViewer, recommendedUpdateDescriptor); } // delete the downloaded .update file, don't leave it laying around File.Delete(recommendedUpdateDescriptor.DownloadedPath); AutoUpdateManagerWithDownloadDescriptorEventArgs afterUpdateAltPathArgs = new AutoUpdateManagerWithDownloadDescriptorEventArgs(this, beforeUpdateAltPathArgs.ProgressViewer, recommendedUpdateDescriptor); this.OnAfterUpdateAlternatePath(this, afterUpdateAltPathArgs); #endregion #region Step 5. Switch to Latest Version if (installed) { /* * Raise the BeforeSwitchToLatestVersion event * */ AutoUpdateManagerWithDownloadDescriptorCancelEventArgs beforeSwitchedArgs = new AutoUpdateManagerWithDownloadDescriptorCancelEventArgs(this, afterUpdateAltPathArgs.ProgressViewer, recommendedUpdateDescriptor, false); this.OnBeforeSwitchToLatestVersion(this, beforeSwitchedArgs); // if switching to the latest version was not cancelled if (!beforeSwitchedArgs.Cancel) { /* * Raise the SwitchToLatestVersion event * */ AutoUpdateManagerWithDownloadDescriptorEventArgs switchToArgs = new AutoUpdateManagerWithDownloadDescriptorEventArgs(this, beforeSwitchedArgs.ProgressViewer, recommendedUpdateDescriptor); this.OnSwitchToLatestVersion(this, switchToArgs); // the rest should be history because the AutoUpdateSnapIn should catch that event and switch to the latest version using the bootstrap } } #endregion } catch(ThreadAbortException) { Debug.WriteLine("The AutoUpdateManager has encountered a ThreadAbortException.\n\tThe auto-update thread has been aborted.", MY_TRACE_CATEGORY); try { // delete the downloaded .update file, don't leave it laying around File.Delete(recommendedUpdateDescriptor.DownloadedPath); } catch(Exception ex) { Debug.WriteLine(ex); } } catch(Exception ex) { //Debug.WriteLine(ex); this.OnException(this, new AutoUpdateExceptionEventArgs(ex)); } }
/// <summary> /// Raises the BeforeQueryForLatestVersion event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void OnBeforeQueryForLatestVersion(object sender, AutoUpdateManagerCancelEventArgs e) { try { if (this.BeforeQueryForLatestVersion != null) this.BeforeQueryForLatestVersion(sender, e); } catch(ThreadAbortException) { } catch(Exception ex) { Debug.WriteLine(ex); } }