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."));
			}
		}
Beispiel #2
0
        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();
			}
		}