public void Run(string[] args, System.Reflection.Assembly executable) { bool tracedExceptionThrown = false; try { using (SplashWindowThread splashThread = new SplashWindowThread(executable, false)) { splashThread.ShowAsynchronously(); splashThread.Window.SetMarqueeMoving(true, true); ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Parsing command line..."); // create a new command line parsing engine CommandLineParsingEngine pe = new CommandLineParsingEngine(args); // determine if we are going to keep the old versions bool keepOld = pe.ToBoolean("keepold"); // the process id of an app int pid = pe.ToInt32("pid"); // whether we should wait on the specified pid to die before launching new version bool wait = pe.ToBoolean("wait"); ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Searching for runnable version..."); // create a search for all of the subdirectories Search search = new Search("Versions", Application.StartupPath, "*", false, false); // find all of the directories DirectoryInfo[] directories = search.GetDirectories(); // create versioned files around each directory that can be parsed to a version VersionedDirectory[] versionedDirectories = this.CreateVersionedFiles(directories); // if we have been instructed to wait on the process specified by pid to die, do it now if (wait && pid != 0) { try { // snag it and wait on it to exit Process p = Process.GetProcessById(pid); if (p != null) { ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Closing previous instance..."); p.WaitForExit(); } } catch(System.Exception systemException) { System.Diagnostics.Trace.WriteLine(systemException); } } ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Selecting latest runnable version..."); // try and start the newest version VersionedDirectory versionStarted; bool startedVersion = this.StartNewestVersion(executable, versionedDirectories, out versionStarted, splashThread.Window); // this will fall back upon older versions until it runs out of versions or one of the versions starts if (!startedVersion) { string exeName = string.Format("{0}.exe", executable.GetName().Name); ExceptionEngine.DisplayException(null, "BootStrap failed for " + exeName, MessageBoxIcon.Stop, MessageBoxButtons.OK, null, "No suitable executable was found or able to be started."); } // if we're not keeping the old versions if (!keepOld) { // delete the older versions if (!this.DeleteOlderVersions(versionedDirectories, versionStarted, splashThread.Window)) { // um, who cares if we can't delete the older versions // also we need to see about security rights to the directories } } // if we started a version if (startedVersion) // notify that we are transferring control now to it... ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Transferring control to version " + versionStarted.Version.ToString() + "..."); } } catch(System.Exception systemException) { tracedExceptionThrown = true; System.Diagnostics.Trace.WriteLine(systemException); System.Windows.Forms.MessageBox.Show(null, systemException.ToString(), "Application Exiting"); Application.ExitThread(); } finally { System.Diagnostics.Trace.WriteLine("'" + Application.ProductName + (tracedExceptionThrown ? "' has terminated because of an exception." : "' has exited gracefully.")); } }
public void Run(string[] args, System.Reflection.Assembly executable) { bool tracedExceptionThrown = false; try { using (SplashWindowThread splashThread = new SplashWindowThread(executable, false)) { splashThread.ShowAsynchronously(); splashThread.Window.SetMarqueeMoving(true, true); ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Parsing command line..."); // create a new command line parsing engine CommandLineParsingEngine pe = new CommandLineParsingEngine(args); // determine if we are going to keep the old versions bool keepOld = pe.ToBoolean("keepold"); // the process id of an app int pid = pe.ToInt32("pid"); // whether we should wait on the specified pid to die before launching new version bool wait = pe.ToBoolean("wait"); ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Searching for runnable version..."); // create a search for all of the subdirectories Search search = new Search("Versions", Application.StartupPath, "*", false, false); // find all of the directories DirectoryInfo[] directories = search.GetDirectories(); // create versioned files around each directory that can be parsed to a version VersionedDirectory[] versionedDirectories = this.CreateVersionedFiles(directories); // if we have been instructed to wait on the process specified by pid to die, do it now if (wait && pid != 0) { try { // snag it and wait on it to exit Process p = Process.GetProcessById(pid); if (p != null) { ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Closing previous instance..."); p.WaitForExit(); } } catch (System.Exception systemException) { System.Diagnostics.Trace.WriteLine(systemException); } } ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Selecting latest runnable version..."); // try and start the newest version VersionedDirectory versionStarted; bool startedVersion = this.StartNewestVersion(executable, versionedDirectories, out versionStarted, splashThread.Window); // this will fall back upon older versions until it runs out of versions or one of the versions starts if (!startedVersion) { string exeName = string.Format("{0}.exe", executable.GetName().Name); ExceptionEngine.DisplayException(null, "BootStrap failed for " + exeName, MessageBoxIcon.Stop, MessageBoxButtons.OK, null, "No suitable executable was found or able to be started."); } // if we're not keeping the old versions if (!keepOld) { // delete the older versions if (!this.DeleteOlderVersions(versionedDirectories, versionStarted, splashThread.Window)) { // um, who cares if we can't delete the older versions // also we need to see about security rights to the directories } } // if we started a version if (startedVersion) { // notify that we are transferring control now to it... ProgressViewer.SetExtendedDescription(splashThread.Window, "Bootstrap: Transferring control to version " + versionStarted.Version.ToString() + "..."); } } } catch (System.Exception systemException) { tracedExceptionThrown = true; System.Diagnostics.Trace.WriteLine(systemException); System.Windows.Forms.MessageBox.Show(null, systemException.ToString(), "Application Exiting"); Application.ExitThread(); } finally { System.Diagnostics.Trace.WriteLine("'" + Application.ProductName + (tracedExceptionThrown ? "' has terminated because of an exception." : "' has exited gracefully.")); } }
/// <summary> /// Runs the current instance of the hosting engine. This creates a blocking thread message loop until a SnapIn calls Application.ExitThread in the context of the hosting engine. /// </summary> /// <param name="args">The command line arguments to pass to the hosting engine. See the CommandLineParsingEngine for capabilities and syntaxes supported.</param> public void Run(string[] args) { try { // create the command line parsing engine _commandLineParsingEngine = new CommandLineParsingEngine(args); // parse the command line for debugging flags this.ParseCommandLineForDebuggingFlags(_splashThread.Window); #region Create directories // create the common app data path, bail if it fails if (!PathCreationEngine.CreateDirectory(_commonDataPath, this, "CommonDataPath")) return; // create the local user app data path, bail if it fails if (!PathCreationEngine.CreateDirectory(_localUserDataPath, this, "LocalUserDataPath")) return; // create the local user logs path, bail if it fails if (!PathCreationEngine.CreateDirectory(_logsDataPath, this, "LogsDataPath")) return; #endregion // rotate the log files this.RotateLogFiles(); // install the custom trace listener so that we can write to our log files this.InstallTraceListener(_splashThread.Window); // if we are in trouble shooting mode, then show the feature and trouble shooting dialog if (SnapInHostingEngine.TroubleshootingMode) FeatureEngine.ShowFeatureWindow(this); #region Read Configuration Files // read or create the configuration engine configuration ProgressViewer.SetExtendedDescription(_splashThread.Window, "Reading configuration " + ConfigurationEngine.DefaultConfigurationName); if (!ConfigurationEngine.ReadOrCreateConfiguration(SnapInHostingEngine.VerboseMode, ConfigurationEngine.DefaultConfigurationName, SnapInHostingEngine.ConfigurationEngineConfigurationFilename, out _configurationEngineConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()), new XmlConfigurationEventHandler(this.OnFormatConfigurationeEngineConfiguration))) return; if (_configurationEngineConfiguration != null) { _configurationEngineConfiguration.TimeToSave += new EventHandler(OnConfigurationEngineConfigurationTimeToSave); } // read or create the installation engine configuration ProgressViewer.SetExtendedDescription(_splashThread.Window, "Reading configuration " + InstallationEngine.DefaultConfigurationName); if (!ConfigurationEngine.ReadOrCreateConfiguration(SnapInHostingEngine.VerboseMode, InstallationEngine.DefaultConfigurationName, SnapInHostingEngine.InstallationEngineConfigurationFilename, out _installationEngineConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()), new XmlConfigurationEventHandler(this.OnFormatInstallationEngineConfiguration))) return; if (_installationEngineConfiguration != null) { _installationEngineConfiguration.TimeToSave += new EventHandler(OnInstallationEngineConfigurationTimeToSave); } // read or create the common configuration ProgressViewer.SetExtendedDescription(_splashThread.Window, "Reading configuration " + SnapInHostingEngine.DefaultCommonConfigurationName); if (!ConfigurationEngine.ReadOrCreateConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.DefaultCommonConfigurationName, SnapInHostingEngine.CommonConfigurationFilename, out _commonConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()), new XmlConfigurationEventHandler(this.OnFormatCommonConfiguration))) return; if (_commonConfiguration != null) { _commonConfiguration.TimeToSave += new EventHandler(OnCommonConfigurationTimeToSave); } // read or create the local user configuration ProgressViewer.SetExtendedDescription(_splashThread.Window, "Reading configuration " + SnapInHostingEngine.DefaultLocalUserConfigurationName); if (!ConfigurationEngine.ReadOrCreateConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.DefaultLocalUserConfigurationName, SnapInHostingEngine.LocalUserConfigurationFilename, out _localUserConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()), new XmlConfigurationEventHandler(this.OnFormatLocalUserConfiguration))) return; if (_localUserConfiguration != null) { _localUserConfiguration.TimeToSave += new EventHandler(OnLocalUserConfigurationTimeToSave); } #endregion #region Register Configuration Files with the ConfigurationEngine // register the installation engine configuration ConfigurationEngine.RegisterFile(this.ConfigurationEngineConfiguration, InstallationEngine.DefaultConfigurationName, SnapInHostingEngine.InstallationEngineConfigurationFilename ); // register the common configuration ConfigurationEngine.RegisterFile(this.ConfigurationEngineConfiguration, SnapInHostingEngine.DefaultCommonConfigurationName, SnapInHostingEngine.CommonConfigurationFilename); // register the local user configuration ConfigurationEngine.RegisterFile(this.ConfigurationEngineConfiguration, SnapInHostingEngine.DefaultLocalUserConfigurationName, SnapInHostingEngine.LocalUserConfigurationFilename); #endregion // search for and create snapins that have not been uninstalled _descriptors = SnapInHostingEngine.SearchForSnapIns(new Search("SnapIns", Application.StartupPath, "*.dll", false, true), _splashThread.Window); // mark all of the descriptors that are missing dependencies SnapInDescriptor.MarkDescriptorsThatAreMissingDependencies(_descriptors); // sort the snapins from the least dependent first to the most dependent last SnapInDescriptor.Sort(_descriptors, true); // mark all of the descriptors that are circularly dependent according to the dependency attributes SnapInDescriptor.MarkDescriptorsThatAreCircularlyDependent(_descriptors); // mark all of the descriptors that have dependencies, which are they themselves circularly dependent SnapInDescriptor.MarkDescriptorsThatHaveDependenciesThatAreCircularlyDependent(_descriptors); // mark all of the descriptors that have dependencies, SnapInDescriptor.MarkDescriptorsThatHaveDependenciesThatAreMissingADependency(_descriptors); // start each SnapIn foreach(SnapInDescriptor descriptor in _descriptors) SnapInHostingEngine.Start(descriptor, true, _splashThread.Window); // close the splash window _splashThread.Window.Close(); // force garbage collection so we can get things rolling GC.Collect(); // fire off the event to notify the world that all of the snapins have been started this.OnAfterSnapInsStarted(this, System.EventArgs.Empty); // if we are not supposed to ignore the message loop if (!_noMessageLoop) { // run the main thread message loop System.Windows.Forms.Application.Run(_applicationContext); } // fire off the event to notify the world that all of the snapins are about to be stopped this.OnBeforeSnapInsStopped(this, System.EventArgs.Empty); // sort the snapins from the most dependent first to the least dependent last SnapInDescriptor.Sort(_descriptors, false); // stop each SnapIn foreach(SnapInDescriptor descriptor in _descriptors) SnapInHostingEngine.Stop(descriptor, true, null); #region Write Configuration Files // write the hosting engine configuration if (!ConfigurationEngine.WriteConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.ConfigurationEngineConfigurationFilename, SnapInHostingEngine.GetExecutingInstance().ConfigurationEngineConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()))) return; // write the hosting engine configuration if (!ConfigurationEngine.WriteConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.InstallationEngineConfigurationFilename, _installationEngineConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()))) return; // write the common configuration if (!ConfigurationEngine.WriteConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.CommonConfigurationFilename, SnapInHostingEngine.GetExecutingInstance().CommonConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()))) return; // write the local user configuration if (!ConfigurationEngine.WriteConfiguration(SnapInHostingEngine.VerboseMode, SnapInHostingEngine.LocalUserConfigurationFilename, SnapInHostingEngine.GetExecutingInstance().LocalUserConfiguration, (_noEncrypt ? null : new RijndaelEncryptionEngine()))) return; #endregion } catch(Exception ex) { Trace.WriteLine(ex); } finally { _instanceManager.Dispose(); } }