static void Main(string[] args) { //Retrive cmdline to pass to new process CommandLineString = ""; for (int i = 0; i < args.Length; i++) { CommandLineString = string.Format("{0} {1}", CommandLineString, args[i]); } CommandLineString += " /appstartversion " + Assembly.GetExecutingAssembly().GetName().Version.ToString(); RestartCommandLineString = CommandLineString + " /restart "; CommandLineArgs = new String[args.Length + 2]; CommandLineArgs[CommandLineArgs.Length - 2] = "/appstartversion"; CommandLineArgs[CommandLineArgs.Length - 1] = Assembly.GetExecutingAssembly().GetName().Version.ToString(); RestartCommandLineArgs = new String[CommandLineArgs.Length + 1]; RestartCommandLineArgs[RestartCommandLineArgs.Length - 1] = "/restart"; AppStartConfig Config = LoadConfig(); if (Config.AppLaunchMode == AppStartConfig.LaunchModes.Process) { StartAndWait_Process(); } else { StartAndWait_Domain(); } }
/********************************************************************* * LoadConfig() **********************************************************************/ private static AppStartConfig LoadConfig() { AppStartConfig Config; //Load the config file which knows where the app lives try { //Try app specific config file name Config = AppStartConfig.Load(CalcConfigFileLocation()); return(Config); } catch (Exception e) { try { //Try default config file name Debug.WriteLine("APPLICATION STARTER: Falling back to try to read appstart.config."); Config = AppStartConfig.Load(AppDomain.CurrentDomain.BaseDirectory + @"AppStart.Config"); return(Config); } catch { HandleTerminalError(e); } } return(null); }
//************************************************************** // GetLatestInstalledVersion() //************************************************************** public static Version GetLatestInstalledVersion() { //Load the AppStart config File string ConfigFilePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); ConfigFilePath = Path.Combine(Directory.GetParent(ConfigFilePath).FullName, "AppStart.config"); AppStartConfig Config = AppStartConfig.Load(ConfigFilePath); AssemblyName AN = AssemblyName.GetAssemblyName(Config.AppExePath); return(AN.Version); }
//************************************************************** // LoadRemoteConfigFile() //************************************************************** private static AppStartConfig LoadRemoteConfigFile(string key, string orgConfigPath) { string NewConfigPath = ""; try { RegistryKey r = Registry.LocalMachine.OpenSubKey(key); NewConfigPath = (string)r.GetValue("InstallDir"); NewConfigPath = Path.Combine(NewConfigPath, Path.GetFileName(orgConfigPath)); return(AppStartConfig.Load(NewConfigPath)); } catch (Exception e) { Debug.WriteLine("Error loading config file at " + NewConfigPath + " as specified by registry key."); throw e; } }
//************************************************************** // Load() //************************************************************** public static AppStartConfig Load(string filePath) { AppStartConfig Config = new AppStartConfig(filePath); try { //Load the xml config file XmlDocument XmlDoc = new XmlDocument(); try { XmlDoc.Load(filePath); } catch (Exception e) { throw new ConfigFileMissingException("Config file '" + filePath + "' is missing.", e); } //Parse out the redirection key string KeyValue = ""; try { XmlNode AppRedirNode = XmlDoc.SelectSingleNode(@"//AppRedirectionKey"); KeyValue = AppRedirNode.InnerText; } //The Key not present case catch (Exception) { KeyValue = ""; } if (KeyValue != "") { return(LoadRemoteConfigFile(KeyValue, filePath)); } //Parse out the AppPath XmlNode AppPathNode = XmlDoc.SelectSingleNode(@"//AppFolderName"); Config.AppFolderName = AppPathNode.InnerText; //Parse out the AppExeName XmlNode AppExeNode = XmlDoc.SelectSingleNode(@"//AppExeName"); Config.AppExeName = AppExeNode.InnerText; //Parse out the AppLauchMode XmlNode AppLaunchModeNode = XmlDoc.SelectSingleNode(@"//AppLaunchMode"); if (AppLaunchModeNode == null) { //Default Value Config.AppLaunchMode = LaunchModes.Process; } else { if (AppLaunchModeNode.InnerText.ToLower(new CultureInfo("en-US")) == "appdomain") { Config.AppLaunchMode = LaunchModes.AppDomain; } else { Config.AppLaunchMode = LaunchModes.Process; } } return(Config); } catch (Exception e) { Debug.WriteLine("Failed to read the appstart config file at: " + filePath); Debug.WriteLine("Make sure that the config file is present & has a valid format"); throw e; } }
//************************************************************** // 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"); try { Config = AppStartConfig.Load(ConfigFilePath); } catch { Debug.WriteLine("APPMANAGER: ThreadAborted: Updater failed to load, stopping download."); return; } 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); AppMan.Manifest.State.DownloadSource = SM.ApplicationUrl; } 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(); OnConnectionStrengthChange (this, ConnStrengthEventArgs ); }
//************************************************************** // Load() //************************************************************** public static AppStartConfig Load(string filePath) { AppStartConfig Config = new AppStartConfig(filePath); try { //Load the xml config file XmlDocument XmlDoc = new XmlDocument(); try { XmlDoc.Load(filePath); } catch(Exception e) { throw new ConfigFileMissingException("Config file '" + filePath + "' is missing.", e); } //Parse out the redirection key string KeyValue = ""; try { XmlNode AppRedirNode = XmlDoc.SelectSingleNode(@"//AppRedirectionKey"); KeyValue = AppRedirNode.InnerText; } //The Key not present case catch (Exception) { KeyValue =""; } if (KeyValue != "") { return LoadRemoteConfigFile(KeyValue, filePath); } //Parse out the AppPath XmlNode AppPathNode = XmlDoc.SelectSingleNode(@"//AppFolderName"); Config.AppFolderName = AppPathNode.InnerText; //Parse out the AppExeName XmlNode AppExeNode = XmlDoc.SelectSingleNode(@"//AppExeName"); Config.AppExeName = AppExeNode.InnerText; //Parse out the AppLauchMode XmlNode AppLaunchModeNode = XmlDoc.SelectSingleNode(@"//AppLaunchMode"); if (AppLaunchModeNode == null) //Default Value Config.AppLaunchMode = LaunchModes.Process; else { if (AppLaunchModeNode.InnerText.ToLower(new CultureInfo("en-US")) == "appdomain") Config.AppLaunchMode = LaunchModes.AppDomain; else Config.AppLaunchMode = LaunchModes.Process; } return Config; } catch (Exception e) { Debug.WriteLine("Failed to read the appstart config file at: " + filePath ); Debug.WriteLine("Make sure that the config file is present & has a valid format"); throw e; } }
//************************************************************** // 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); AppMan.Manifest.State.DownloadSource = SM.ApplicationUrl; } 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(); } }