//************************************************************** // CheckForUpdates() // - Checks for an update // - This is a sync call... normally called by the poller object // on the poller thread. //************************************************************** public bool CheckForUpdates() { Debug.WriteLine("APPMANAGER: Checking for updates."); bool retValue = false; //If the OnCheckForUpdate event the caller is doing the check if (OnCheckForUpdate != null) { retValue = OnCheckForUpdate(this, new EventArgs()); } else //otherwise do the check ourselves { //If versioning is enabled check to see if the version file has changed. if (ChangeDetectionMode == ChangeDetectionModes.ServerManifestCheck) { ServerManifest vm = new ServerManifest(); vm.Load(UpdateUrl); retValue = vm.IsServerVersionNewer(GetLatestInstalledVersion()); } else //If versioning is not enabled, check the files themselves { Resource currentResource; foreach (Object r in Manifest.Resources.ResourceList) { currentResource = (Resource)(((DictionaryEntry)r).Value); string url = UpdateUrl + currentResource.Name; string FilePath = currentResource.FilePath; if (WebFileLoader.CheckForFileUpdate(url, FilePath)) { retValue = true; } } } } //Fire the OnUpdateDetected Event on the UI thread if (OnUpdateDetected != null) { foreach (UpdateDetectedEventHandler UC in OnUpdateDetected.GetInvocationList()) { UpdateDetectedEventArgs ud = new UpdateDetectedEventArgs(); ud.UpdateDetected = retValue; EventControl.BeginInvoke(UC, new object[] { this, ud }); } } return(retValue); }
//************************************************************** // RunThread() //************************************************************** public void RunThread() { Debug.WriteLine("APPMANAGER: Starting Update"); //Load the AppStart config File string ConfigFilePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); ConfigFilePath = Path.Combine(Directory.GetParent(ConfigFilePath).FullName, "AppStart.config"); Config = AppStartConfig.Load(ConfigFilePath); try { //Mark in the manifest that a download is in progress. Persisted in //manifest in case the app is stop & restarted during the download. if (AppMan.Manifest.State.Phase == UpdatePhases.Complete) { AppMan.Manifest.State.Phase = UpdatePhases.Scavenging; AppMan.Manifest.State.UpdateFailureCount = 0; AppMan.Manifest.State.UpdateFailureEncoutered = false; AppMan.Manifest.State.DownloadDestination = CreateTempDirectory(); if (AppMan.ChangeDetectionMode == ChangeDetectionModes.ServerManifestCheck) { ServerManifest SM = new ServerManifest(); SM.Load(AppMan.UpdateUrl); //download from the web and desserialise it into the object AppMan.Manifest.State.DownloadSource = SM.ApplicationUrl; //new: krishna added this to enable specifying files explicitly instead of deep copying //a directory using HTTP-DAV. AppMan.Manifest.State.FilesToDownload = SM.FilesToDownload; } else { AppMan.Manifest.State.DownloadSource = AppMan.UpdateUrl; } AppMan.Manifest.Update(); } //Scavenge Existing Directories if (AppMan.Manifest.State.Phase == UpdatePhases.Scavenging) { Debug.WriteLine("APPMANAGER: Scavaging older versions"); Scavenge(); AppMan.Manifest.State.Phase = UpdatePhases.Downloading; AppMan.Manifest.Update(); } //Download the New Version if (AppMan.Manifest.State.Phase == UpdatePhases.Downloading) { Debug.WriteLine("APPMANAGER: Downloading new version"); Download(); AppMan.Manifest.State.Phase = UpdatePhases.Validating; AppMan.Manifest.Update(); } //Validate the downloaded bits if (AppMan.Manifest.State.Phase == UpdatePhases.Validating) { Debug.WriteLine("APPMANAGER: Downloading new version"); Validate(); AppMan.Manifest.State.Phase = UpdatePhases.Merging; AppMan.Manifest.Update(); } //Merge the existing version into the new version if (AppMan.Manifest.State.Phase == UpdatePhases.Merging) { Debug.WriteLine("APPMANAGER: Merging current & new versions"); MergeDirectory(AppDomain.CurrentDomain.BaseDirectory, AppMan.Manifest.State.DownloadDestination); AppMan.Manifest.State.Phase = UpdatePhases.Finalizing; AppMan.Manifest.Update(); } //Finalize the update. Rename the new version directory, etc... if (AppMan.Manifest.State.Phase == UpdatePhases.Finalizing) { Debug.WriteLine("APPMANAGER: Finalizing update"); FinalizeUpdate(); } //Reset Update State AppMan.Manifest.State.Phase = UpdatePhases.Complete; AppMan.Manifest.State.UpdateFailureCount = 0; AppMan.Manifest.State.UpdateFailureEncoutered = false; AppMan.Manifest.State.DownloadSource = ""; AppMan.Manifest.State.DownloadDestination = ""; AppMan.Manifest.State.NewVersionDirectory = ""; AppMan.Manifest.Update(); } catch (ThreadAbortException) { Thread.ResetAbort(); Debug.WriteLine("APPMANAGER: ThreadAborted: Updater Thread stopped, stopping download."); return; } catch (Exception e) { UpdateEventArgs.FailureException = e; } if (AppMan.Manifest.State.Phase != UpdatePhases.Complete) { HandleUpdateFailure(); } else { HandleUpdateSuccess(); } }
//************************************************************** // RunThread() //************************************************************** public void RunThread() { Debug.WriteLine("APPMANAGER: Starting Update"); //Load the AppStart config File string ConfigFilePath =Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); ConfigFilePath = Path.Combine(Directory.GetParent(ConfigFilePath).FullName,"AppStart.config"); Config = AppStartConfig.Load(ConfigFilePath); try { //Mark in the manifest that a download is in progress. Persisted in //manifest in case the app is stop & restarted during the download. if (AppMan.Manifest.State.Phase == UpdatePhases.Complete) { AppMan.Manifest.State.Phase = UpdatePhases.Scavenging; AppMan.Manifest.State.UpdateFailureCount=0; AppMan.Manifest.State.UpdateFailureEncoutered = false; AppMan.Manifest.State.DownloadDestination = CreateTempDirectory(); if (AppMan.ChangeDetectionMode == ChangeDetectionModes.ServerManifestCheck) { ServerManifest SM = new ServerManifest(); SM.Load(AppMan.UpdateUrl); //download from the web and desserialise it into the object AppMan.Manifest.State.DownloadSource = SM.ApplicationUrl; //new: krishna added this to enable specifying files explicitly instead of deep copying //a directory using HTTP-DAV. AppMan.Manifest.State.FilesToDownload = SM.FilesToDownload; } else { AppMan.Manifest.State.DownloadSource = AppMan.UpdateUrl; } AppMan.Manifest.Update(); } //Scavenge Existing Directories if (AppMan.Manifest.State.Phase == UpdatePhases.Scavenging) { Debug.WriteLine("APPMANAGER: Scavaging older versions"); Scavenge(); AppMan.Manifest.State.Phase=UpdatePhases.Downloading; AppMan.Manifest.Update(); } //Download the New Version if (AppMan.Manifest.State.Phase == UpdatePhases.Downloading) { Debug.WriteLine("APPMANAGER: Downloading new version"); Download(); AppMan.Manifest.State.Phase = UpdatePhases.Validating; AppMan.Manifest.Update(); } //Validate the downloaded bits if (AppMan.Manifest.State.Phase == UpdatePhases.Validating) { Debug.WriteLine("APPMANAGER: Downloading new version"); Validate(); AppMan.Manifest.State.Phase = UpdatePhases.Merging; AppMan.Manifest.Update(); } //Merge the existing version into the new version if (AppMan.Manifest.State.Phase == UpdatePhases.Merging) { Debug.WriteLine("APPMANAGER: Merging current & new versions"); MergeDirectory(AppDomain.CurrentDomain.BaseDirectory,AppMan.Manifest.State.DownloadDestination); AppMan.Manifest.State.Phase = UpdatePhases.Finalizing; AppMan.Manifest.Update(); } //Finalize the update. Rename the new version directory, etc... if (AppMan.Manifest.State.Phase == UpdatePhases.Finalizing) { Debug.WriteLine("APPMANAGER: Finalizing update"); FinalizeUpdate(); } //Reset Update State AppMan.Manifest.State.Phase = UpdatePhases.Complete; AppMan.Manifest.State.UpdateFailureCount=0; AppMan.Manifest.State.UpdateFailureEncoutered = false; AppMan.Manifest.State.DownloadSource = ""; AppMan.Manifest.State.DownloadDestination = ""; AppMan.Manifest.State.NewVersionDirectory = ""; AppMan.Manifest.Update(); } catch (ThreadAbortException) { Thread.ResetAbort(); Debug.WriteLine("APPMANAGER: ThreadAborted: Updater Thread stopped, stopping download."); return; } catch (Exception e) { UpdateEventArgs.FailureException = e; } if (AppMan.Manifest.State.Phase != UpdatePhases.Complete) HandleUpdateFailure(); else HandleUpdateSuccess(); }
//************************************************************** // OnAssemblyResolve() // - This code is what does the auto-download of missing files //************************************************************** private Assembly OnAssemblyResolve(Object sender, ResolveEventArgs args) { //Check to see if the AssemblyLoad in this event is what caused the //event to fire again. If so, the load failed. if (LoadingAssembly == true) { return(null); } LoadingAssembly = true; string[] AssemblyNameParts = args.Name.Split(new Char[] { ',' }, 2); string AssemblyName = AssemblyNameParts[0] + ".dll"; string FilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AssemblyName); string url; if (ChangeDetectionMode == ChangeDetectionModes.DirectFileCheck) { url = UpdateUrl + AssemblyName; } else { ServerManifest SM = new ServerManifest(); SM.Load(UpdateUrl); url = Path.Combine(SM.ApplicationUrl, AssemblyName); } Debug.WriteLine("APPMANAGER: Auto-downloading assembly: " + AssemblyName + ". From: " + url); try { WebFileLoader.UpdateFile(url, FilePath); } catch (Exception e) { Debug.WriteLine("APPMANAGER: Failed to download the missing assembly from the web server."); Debug.WriteLine("APPMANAGER: " + e.ToString()); if (ShowDefaultUI) { MessageBox.Show("Unable to auto-download the missing parts of the application from:\r\n" + url + "\r\n\r\n" + "Make sure your connected to the network. If the problem persists re-install the application."); } return(null); } Assembly assembly; try { assembly = Assembly.Load(args.Name); } catch (Exception e) { Debug.WriteLine("APPMANAGER: Failed to load the auto-downloaded assembly."); Debug.WriteLine("APPMANAGER: " + e.ToString()); return(null); } finally { LoadingAssembly = false; } return(assembly); }
//************************************************************** // OnAssemblyResolve() // - This code is what does the auto-download of missing files //************************************************************** private Assembly OnAssemblyResolve(Object sender,ResolveEventArgs args) { //Check to see if the AssemblyLoad in this event is what caused the //event to fire again. If so, the load failed. if (LoadingAssembly==true) return null; LoadingAssembly=true; string[] AssemblyNameParts = args.Name.Split(new Char[] {','}, 2); string AssemblyName = AssemblyNameParts[0] + ".dll"; string FilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AssemblyName); string url; if (ChangeDetectionMode == ChangeDetectionModes.DirectFileCheck) url = UpdateUrl + AssemblyName; else { ServerManifest SM = new ServerManifest(); SM.Load(UpdateUrl); url = Path.Combine(SM.ApplicationUrl,AssemblyName); } Debug.WriteLine("APPMANAGER: Auto-downloading assembly: " + AssemblyName + ". From: " + url); try { WebFileLoader.UpdateFile(url, FilePath); } catch (Exception e) { Debug.WriteLine("APPMANAGER: Failed to download the missing assembly from the web server."); Debug.WriteLine("APPMANAGER: " + e.ToString()); if (ShowDefaultUI) MessageBox.Show("Unable to auto-download the missing parts of the application from:\r\n" + url + "\r\n\r\n" + "Make sure your connected to the network. If the problem persists re-install the application."); return null; } Assembly assembly; try { assembly = Assembly.Load(args.Name); } catch (Exception e) { Debug.WriteLine("APPMANAGER: Failed to load the auto-downloaded assembly."); Debug.WriteLine("APPMANAGER: " + e.ToString()); return null; } finally { LoadingAssembly=false; } return assembly; }
//************************************************************** // CheckForUpdates() // - Checks for an update // - This is a sync call... normally called by the poller object // on the poller thread. //************************************************************** public bool CheckForUpdates() { Debug.WriteLine("APPMANAGER: Checking for updates."); bool retValue = false; //If the OnCheckForUpdate event the caller is doing the check if (OnCheckForUpdate != null) { retValue = OnCheckForUpdate(this, new EventArgs()); } else //otherwise do the check ourselves { //If versioning is enabled check to see if the version file has changed. if (ChangeDetectionMode == ChangeDetectionModes.ServerManifestCheck) { ServerManifest vm = new ServerManifest(); vm.Load(UpdateUrl); retValue = vm.IsServerVersionNewer(GetLatestInstalledVersion()); } else //If versioning is not enabled, check the files themselves { Resource currentResource; foreach(Object r in Manifest.Resources.ResourceList) { currentResource = (Resource)(((DictionaryEntry)r).Value); string url = UpdateUrl + currentResource.Name; string FilePath = currentResource.FilePath; if( WebFileLoader.CheckForFileUpdate(url, FilePath)) retValue = true; } } } //Fire the OnUpdateDetected Event on the UI thread if (OnUpdateDetected != null) { foreach ( UpdateDetectedEventHandler UC in OnUpdateDetected.GetInvocationList()) { UpdateDetectedEventArgs ud = new UpdateDetectedEventArgs(); ud.UpdateDetected = retValue; EventControl.BeginInvoke(UC,new object[] {this,ud}); } } return retValue; }