/// <summary>
        /// Returns the filename using the specified key from the specified configuration
        /// </summary>
        /// <param name="configuration">The configuration from which the filename will be extracted</param>
        /// <param name="key">The key by which the filename was saved</param>
        /// <returns></returns>
        public static string GetRegisteredFilename(XmlConfiguration configuration, string key)
        {
            ConfigurationEngine.ResetLastException();
            try
            {
                if (configuration != null)
                {
                    if (key != null && key != string.Empty)
                    {
                        XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
                        if (category != null)
                        {
                            XmlConfigurationOption option = null;

                            option = category.Options[key];
                            if (option != null)
                            {
                                return((string)option.Value);
                            }
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                _lastException = systemException;
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(string.Empty);
        }
        /// <summary>
        /// Reads a configuration using the specified encryption engine from the specified path
        /// </summary>
        /// <param name="encryptionEngine">The encryption engine to use while reading the configuration, null if no decryption is desired</param>
        /// <param name="configuration">The configuration to be read into</param>
        /// <param name="path">The path to be read from</param>
        /// <returns></returns>
        public static bool ReadConfiguration(FileEncryptionEngine encryptionEngine, out XmlConfiguration configuration, string path)
        {
            Stream stream = null;

            ConfigurationEngine.ResetLastException();
            try
            {
                configuration = new XmlConfiguration();
                stream        = (encryptionEngine != null ? encryptionEngine.CreateDecryptorStream(path) : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None));
                XmlConfigurationReader reader = new XmlConfigurationReader();
                configuration      = reader.Read(stream);
                configuration.Path = path;
                configuration.SetHasUnpersistedChanges(false);

                return(true);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
                _lastException = systemException;
            }
            finally
            {
                try
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
                catch { }
            }
            configuration = null;
            return(false);
        }
 /// <summary>
 /// Returns a Hashtable containing the key and filename of each file that is registered in the specified configuration
 /// </summary>
 /// <param name="configuration">The configuration in which the search will occur</param>
 /// <returns></returns>
 public static Hashtable GetRegisteredFiles(XmlConfiguration configuration)
 {
     ConfigurationEngine.ResetLastException();
     try
     {
         if (configuration != null)
         {
             XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
             if (category != null)
             {
                 Hashtable table = new Hashtable();
                 foreach (XmlConfigurationOption option in category.Options)
                 {
                     table.Add(option.ElementName, (string)option.Value);
                 }
                 return(table);
             }
         }
     }
     catch (System.Exception systemException)
     {
         _lastException = systemException;
         System.Diagnostics.Trace.WriteLine(systemException);
     }
     return(new Hashtable());
 }
Example #4
0
        /// <summary>
        /// Reads an XmlConfiguration from a System.IO.Stream
        /// </summary>
        /// <param name="stream">The stream that contains the XmlConfiguration file</param>
        /// <param name="configuration">The configuration to load into</param>
        /// <returns></returns>
        public XmlConfiguration Read(Stream stream, XmlConfiguration configuration)
        {
            try
            {
                /// create a new xml document
                XmlDocument doc = new XmlDocument();

                /// load it from the stream
                doc.Load(stream);

                /// create a new xpath navigator so that we can traverse the elements inside the xml
                XPathNavigator navigator = doc.CreateNavigator();

                /// move to the version element
                navigator.MoveToFirstChild();

                /// move to the file format description element
                navigator.MoveToNext();

                this.ReadConfiguration(navigator, configuration);

                return(configuration);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(null);
        }
Example #5
0
        /// <summary>
        /// Adds the specified configuration to the selected configurations displayed by this control
        /// </summary>
        /// <param name="configuration"></param>
        public void AddConfiguration(XmlConfiguration configuration)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new AddConfigurationInvoker(this.AddConfiguration), new object[] { configuration });
                return;
            }

            try
            {
                if (configuration != null)
                {
                    configuration.Changed += new XmlConfigurationElementEventHandler(OnConfigurationChanged);
                    if (_placeElementsIntoEditMode)
                    {
                        configuration.BeginEdit();
                    }
                    _selectedConfigurations.Add(configuration);
                    this.AddNodesForCategories(_treeView, null, configuration.Categories);
                    this.AddXmlTabForConfiguration(configuration);
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
Example #6
0
        /// <summary>
        /// Adds an Xml tab for the specified configuration
        /// </summary>
        /// <param name="configuration"></param>
        private void AddXmlTabForConfiguration(XmlConfiguration configuration)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new AddXmlTabForConfigurationInvoker(this.AddXmlTabForConfiguration), new object[] { configuration });
                return;
            }

            try
            {
                this.tabControlXmlViews.SuspendLayout();

                XmlConfigurationXmlBehindViewer view = new XmlConfigurationXmlBehindViewer();
                view.Xml = configuration.ToXml();

                TabPage page = new TabPage(configuration.ElementName);
                page.Controls.Add(view);
                view.Parent = page;
                view.Dock   = DockStyle.Fill;

                this.tabControlXmlViews.TabPages.Add(page);
                this.tabControlXmlViews.ResumeLayout(true);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
Example #7
0
        /// <summary>
        /// Removes the specified configuration from the selected configurations diplayed by this control, optionally attempts to restore the location
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="keepLocationIfPossible"></param>
        public void RemoveConfiguration(XmlConfiguration configuration, bool keepLocationIfPossible)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new RemoveConfigurationInvoker(this.RemoveConfiguration), new object[] { configuration, keepLocationIfPossible });
                return;
            }

            try
            {
                if (configuration != null)
                {
                    if (_selectedConfigurations.Contains(configuration))
                    {
                        string   path = null;
                        TreeNode n    = _treeView.SelectedNode;
                        if (n != null)
                        {
                            path = n.FullPath;
                        }

                        _selectedConfigurations.Remove(configuration);

                        this.RefreshDisplay(path, keepLocationIfPossible);
                    }
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
        /// <summary>
        /// Writes a configuration to the XmlDocument
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="parent"></param>
        /// <param name="configuration"></param>
        /// <param name="alwaysPersist"></param>
        private void WriteConfiguration(XmlDocument doc, XmlElement parent, XmlConfiguration configuration, bool alwaysPersist)
        {
            try
            {
                if (configuration.Persistent || alwaysPersist)
                {
//					System.Diagnostics.Trace.WriteLine("Writing configuration '" + configuration.ElementName + "'");

                    /// create an element for the category
                    XmlElement child = doc.CreateElement(@"Configuration");

                    /// write the properties of this category
                    child.SetAttribute(@"ElementName", configuration.ElementName);
                    child.SetAttribute(@"HasChanges", XmlConvert.ToString(configuration.HasChanges));
                    child.SetAttribute(@"Category", configuration.Category);
                    child.SetAttribute(@"Description", configuration.Description);
                    child.SetAttribute(@"DisplayName", configuration.DisplayName);
                    child.SetAttribute(@"Hidden", XmlConvert.ToString(configuration.Hidden));

                    /// append the child to our parent
                    parent.AppendChild(child);

                    this.WriteCategories(doc, child, configuration.Categories, alwaysPersist);
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
        }
Example #9
0
 public void Remove(XmlConfiguration configuration)
 {
     if (this.Contains(configuration))
     {
         base.InnerList.Remove(configuration);
     }
 }
        /// <summary>
        /// Writes an entire configuration file using the specified configuration and stream.
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="stream"></param>
        /// <param name="alwaysPersist"></param>
        public void Write(XmlConfiguration configuration, Stream stream, bool alwaysPersist)
        {
            try
            {
                /// create a new xml document
                XmlDocument doc = new XmlDocument();

                /// create the root element
                XmlElement root = doc.CreateElement(@"ConfigurationFile");

                /// append the root element as the first element
                doc.AppendChild(root);

                /// mark the xml as version 1.0 compliant
                XmlDeclaration versionDeclaration = doc.CreateXmlDeclaration(@"1.0", null, null);

                /// insert the version element as the first element
                doc.InsertBefore(versionDeclaration, root);

                this.WriteConfiguration(doc, root, configuration, alwaysPersist);

                /// save the xml document to the stream
                doc.Save(stream);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.Write(systemException);
            }
        }
Example #11
0
        public override bool ApplyChanges(ISupportsEditing editableObject, SupportedEditingActions actions)
        {
            if (base.ApplyChanges(editableObject, actions))
            {
                XmlConfiguration configuration = editableObject as XmlConfiguration;
                if (configuration != null)
                {
                    if (_isBeingEdited)
                    {
                        this.BeginInit();
                    }

                    if (_categories != null)
                    {
                        _categories.ApplyChanges((ISupportsEditing)configuration.Categories, actions);
                    }

                    if (_isBeingEdited)
                    {
                        this.EndInit();
                    }
                }
                return(true);
            }
            return(false);
        }
		public void Remove(XmlConfiguration configuration)
		{
			if (this.Contains(configuration))
			{
				base.InnerList.Remove(configuration);
			}
		}
        /// <summary>
        /// Registers the file using the specified key in the specified configuration. If the key already exists, the file will be written to the existing key.
        /// </summary>
        /// <param name="configuration">The configuration in which the file will be registered</param>
        /// <param name="key">The key by which the file will be registered</param>
        /// <param name="filename">The filename that will be registered</param>
        /// <returns></returns>
        public static bool RegisterFile(XmlConfiguration configuration, string key, string filename)
        {
            ConfigurationEngine.ResetLastException();
            try
            {
                if (configuration != null)
                {
                    if (key != null && key != string.Empty)
                    {
                        XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
                        if (category != null)
                        {
                            XmlConfigurationOption option = null;

                            option = category.Options[key];
                            if (option == null)
                            {
                                option             = category.Options[key, true, filename];
                                option.Category    = @"Registered Files";
                                option.Description = @"This indicates a configuration file that is registered and ready to be accessed via the ConfigurationEngine.";
                            }
                            option.Value = filename;
                            return(true);
                        }
                    }
                }
            }
            catch (System.Exception systemException)
            {
                _lastException = systemException;
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(false);
        }
		/// <summary>
		/// Writes a configuration using the specified encryption engine to the specified path
		/// </summary>
		/// <param name="encryptionEngine">The encryption engine to use while writing the configuration, null if no encryption is desired</param>
		/// <param name="configuration">The confiruration to write</param>
		/// <param name="path">The path to write it to</param>
		/// <returns></returns>
		public static bool WriteConfiguration(FileEncryptionEngine encryptionEngine, XmlConfiguration configuration, string path)
		{	
			Stream stream = null;
			ConfigurationEngine.ResetLastException();
			try
			{
				if (configuration != null)
				{
					if (configuration.HasUnpersistedChanges())
					{
						configuration.AcceptChanges();						
						stream = (encryptionEngine != null ? encryptionEngine.CreateEncryptorStream(path) : new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None));
						XmlConfigurationWriter writer = new XmlConfigurationWriter();				
						writer.Write(configuration, stream, false);	
						configuration.SetHasUnpersistedChanges(false);
					}
					return true;			
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
				_lastException = systemException;
			}
			finally
			{
				try 
				{
					if (stream != null) stream.Close();
				}
				catch { }
			}
			return false;
		}
Example #15
0
        /// <summary>
        /// Gets an XmlConfiguration using a elementName, optionally creates a new or loads an existing configuration (.xml) file using the path specified, and optionally adds it to the collection if new
        /// </summary>
        /// <param name="elementName">The elementName by which this collection will be accessed</param>
        /// <param name="createIfNotFound">A flag indicating whether the configuration should be created if it does not exist</param>
        /// <param name="path">The path to the configuration</param>
        public XmlConfiguration this[string elementName, bool createIfNotFound, bool addToCollectionIfNew, string path]
        {
            get
            {
                /// try and find the configuration in the collection
                XmlConfiguration configuration = this[elementName];

                /// if it's not in the collection
                if (configuration == null)
                {
                    /// perhaps it does in the filesystem, if so then read it, and optionally add it to the collection
                    if (File.Exists(path))
                    {
                        try
                        {
                            FileStream             stream = new FileStream(path, FileMode.Open, FileAccess.Read);
                            XmlConfigurationReader reader = new XmlConfigurationReader();
                            configuration      = reader.Read(stream);
                            configuration.Path = path;
                            stream.Close();

                            if (addToCollectionIfNew)
                            {
                                this.Add(configuration);
                            }

                            return(configuration);
                        }
                        catch (System.Exception systemException)
                        {
                            System.Diagnostics.Trace.WriteLine(systemException);
                        }
                    }

                    /// apparently it doesnt' exist in the filesystem
                    if (createIfNotFound)
                    {
                        /// so create a new file
                        configuration             = new XmlConfiguration();
                        configuration.Path        = path;
                        configuration.ElementName = elementName;

                        /// save the blank config
                        Directory.CreateDirectory(path);
                        FileStream             stream = new FileStream(path, FileMode.Create, FileAccess.Write);
                        XmlConfigurationWriter writer = new XmlConfigurationWriter();
                        writer.Write(configuration, stream, false);
                        stream.Close();

                        /// add it to the config if so instructed
                        if (addToCollectionIfNew)
                        {
                            this.Add(configuration);
                        }
                    }
                }
                return(configuration);
            }
        }
Example #16
0
 public bool Contains(XmlConfiguration configuration)
 {
     foreach (XmlConfiguration config in base.InnerList)
     {
         if (config.ElementName == configuration.ElementName)
         {
             return(true);
         }
     }
     return(false);
 }
		public int Add(XmlConfiguration configuration)
		{
			if (this.Contains(configuration))
				throw new ArgumentException("ElementName already exists. ElementName in collection: " + configuration.ElementName + " ElementName being added: " + configuration.ElementName);

			int index = base.InnerList.Add(configuration);
			
			/// bind to events 

			return 0;
		}
Example #18
0
        public int Add(XmlConfiguration configuration)
        {
            if (this.Contains(configuration))
            {
                throw new ArgumentException("ElementName already exists. ElementName in collection: " + configuration.ElementName + " ElementName being added: " + configuration.ElementName);
            }

            int index = base.InnerList.Add(configuration);

            /// bind to events

            return(0);
        }
Example #19
0
        /// <summary>
        /// Reads a configuration using the specified XPathNavigator
        /// </summary>
        /// <param name="navigator"></param>
        /// <returns></returns>
        private XmlConfiguration ReadConfiguration(XPathNavigator navigator, XmlConfiguration configuration)
        {
            if (navigator.MoveToFirstChild())
            {
                if (string.Compare(navigator.Name, @"Configuration", true) == 0)
                {
                    // does the cateogry have attributes, it should!
                    if (navigator.HasAttributes)
                    {
                        // break off yet another clone to navigate the attributes of this element
                        XPathNavigator attributesNavigator = navigator.Clone();
                        if (attributesNavigator.MoveToFirstAttribute())
                        {
                            configuration.ElementName = attributesNavigator.Value;

                            while (attributesNavigator.MoveToNextAttribute())
                            {
                                switch (attributesNavigator.Name)
                                {
                                case @"HasChanges":
                                    configuration.HasChanges = XmlConvert.ToBoolean(attributesNavigator.Value);
                                    break;

                                case @"Category":
                                    configuration.Category = attributesNavigator.Value;
                                    break;

                                case @"Description":
                                    configuration.Description = attributesNavigator.Value;
                                    break;

                                case @"DisplayName":
                                    configuration.DisplayName = attributesNavigator.Value;
                                    break;

                                case @"Hidden":
                                    configuration.Hidden = XmlConvert.ToBoolean(attributesNavigator.Value);
                                    break;
                                }
                                ;
                            }
                        }
                    }
                }
            }

            // recursively read the categories within this configuration file
            this.ReadCategories(navigator, configuration.Categories);

            return(configuration);
        }
Example #20
0
        /// <summary>
        /// Clones this configuration
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            XmlConfiguration        clone   = null;
            XmlConfigurationElement element = (XmlConfigurationElement)base.Clone();

            if (element != null)
            {
                clone = new XmlConfiguration(element);
                clone.ResetBeforeEdit();
                clone.ResetChanged();
                clone.ResetAfterEdit();
                clone.Path = this.Path;
                clone.SetHasUnpersistedChanges(this.HasUnpersistedChanges());
                clone.Categories = (XmlConfigurationCategoryCollection)this.Categories.Clone();
            }
            return(clone);
        }
		public void Add(XmlConfiguration[] configurations)
		{
			if (configurations != null)
			{
				//				throw new ArgumentNullException("configuration");

				foreach(XmlConfiguration configuration in configurations)
				{
					try
					{
						this.Add(configuration);
					}
					catch(System.Exception systemException)
					{
						System.Diagnostics.Trace.WriteLine(systemException);
					}
				}
			}
		}
Example #22
0
        public override bool ApplyToSelf(ISupportsEditing editableObject, SupportedEditingActions actions)
        {
            if (base.ApplyToSelf(editableObject, actions))
            {
                XmlConfiguration configuration = editableObject as XmlConfiguration;
                if (configuration != null)
                {
                    if (_categories != null)
                    {
                        _categories.ApplyToSelf((ISupportsEditing)configuration.Categories, actions);
                    }
                }
                return(true);
            }

            this.ItIsNowTimeToSave();

            return(false);
        }
Example #23
0
        /// <summary>
        /// Reads an XmlConfiguration from a System.IO.Stream
        /// </summary>
        /// <param name="stream">The stream that contains the XmlConfiguration file</param>
        /// <returns></returns>
        public XmlConfiguration Read(Stream stream)
        {
            try
            {
                // create a new xml document
                XmlDocument doc = new XmlDocument();

                // load it from the stream
                doc.Load(stream);

                // create a new xpath navigator so that we can traverse the elements inside the xml
                XPathNavigator navigator = doc.CreateNavigator();

                // move to the version element
                navigator.MoveToFirstChild();

                // move to the file format description element
                navigator.MoveToNext();

                // create a new configuration
                XmlConfiguration configuration = new XmlConfiguration();

                // begin initialization so that events do not fire inside the configuration
                configuration.BeginInit();

                // using the xpath navigator, read the xml document and turn it into a configuration
                this.ReadConfiguration(navigator, configuration);

                // end initialization
                configuration.EndInit();

                return(configuration);
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
            }
            return(null);
        }
        /// <summary>
        /// Writes a configuration using the specified encryption engine to the specified path
        /// </summary>
        /// <param name="encryptionEngine">The encryption engine to use while writing the configuration, null if no encryption is desired</param>
        /// <param name="configuration">The confiruration to write</param>
        /// <param name="path">The path to write it to</param>
        /// <returns></returns>
        public static bool WriteConfiguration(FileEncryptionEngine encryptionEngine, XmlConfiguration configuration, string path)
        {
            Stream stream = null;

            ConfigurationEngine.ResetLastException();
            try
            {
                if (configuration != null)
                {
                    if (configuration.HasUnpersistedChanges())
                    {
                        configuration.AcceptChanges();
                        stream = (encryptionEngine != null ? encryptionEngine.CreateEncryptorStream(path) : new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None));
                        XmlConfigurationWriter writer = new XmlConfigurationWriter();
                        writer.Write(configuration, stream, false);
                        configuration.SetHasUnpersistedChanges(false);
                    }
                    return(true);
                }
            }
            catch (System.Exception systemException)
            {
                System.Diagnostics.Trace.WriteLine(systemException);
                _lastException = systemException;
            }
            finally
            {
                try
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
                catch { }
            }
            return(false);
        }
		/// <summary>
		/// Parses the category specified in the configuration specified for the type specified, and returns an array of Versions that are listed in the category.
		/// </summary>
		/// <param name="configuration">The configuration to parse</param>
		/// <param name="type">The type to search for</param>
		/// <param name="categoryName">The category to search in</param>
		/// <returns></returns>
		public static Version[] GetListedVersionsOfType(XmlConfiguration configuration, Type type, CategoryNames categoryName)
		{
			try
			{				
				if (configuration != null)
				{					
					if (type != null)
					{
						// start in the specified category
						XmlConfigurationCategory searchCategory = configuration.Categories[@"SnapIns\" + categoryName.ToString()];
						if (searchCategory != null)
						{
							// enumerate the type category, each subcategory is the full name of a type that is listed
							foreach(XmlConfigurationCategory typeCategory in searchCategory.Categories)
							{
								// compare the category's element name to the full name of the type specified
								if (string.Compare(typeCategory.ElementName, type.FullName, false) == 0)
								{
									// enumerate the version category, each subcategory is the version number of the type
									ArrayList array = new ArrayList();
									foreach(XmlConfigurationCategory versionCategory in typeCategory.Categories)
									{
										Version v = new Version(versionCategory.ElementName);
										array.Add(v);
									}
									return array.ToArray(typeof(Version)) as Version[];
								}
							}
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}			
			return new Version[] {};
		}
Example #26
0
 public void AddConfiguration(XmlConfiguration configuration)
 {
     _xmlConfigurationView.AddConfiguration(configuration);
 }
		public bool Contains(XmlConfiguration configuration)
		{
			foreach(XmlConfiguration config in base.InnerList)
				if (config.ElementName == configuration.ElementName)
					return true;
			return false;
		}
		/// <summary>
		/// Reads an XmlConfiguration from a System.IO.Stream
		/// </summary>
		/// <param name="stream">The stream that contains the XmlConfiguration file</param>
		/// <param name="configuration">The configuration to load into</param>
		/// <returns></returns>
		public XmlConfiguration Read(Stream stream, XmlConfiguration configuration)
		{
			try
			{
				/// create a new xml document
				XmlDocument doc = new XmlDocument();

				/// load it from the stream
				doc.Load(stream);

				/// create a new xpath navigator so that we can traverse the elements inside the xml
				XPathNavigator navigator = doc.CreateNavigator();
				
				/// move to the version element
				navigator.MoveToFirstChild(); 

				/// move to the file format description element
				navigator.MoveToNext();	
					
				this.ReadConfiguration(navigator, configuration);

				return configuration;
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}		
			return null;
		}
		public XmlConfigurationEventArgs(XmlConfiguration configuration, XmlConfigurationElementActions action) : base(configuration, action)
		{
				
		}
		public void RemoveConfiguration(XmlConfiguration configuration, bool keepLocationIfPossible)
		{
			_xmlConfigurationView.RemoveConfiguration(configuration, keepLocationIfPossible);
		}
		/// <summary>
		/// Writes a configuration to the XmlDocument
		/// </summary>
		/// <param name="doc"></param>
		/// <param name="parent"></param>
		/// <param name="configuration"></param>
		/// <param name="alwaysPersist"></param>
		private void WriteConfiguration(XmlDocument doc, XmlElement parent, XmlConfiguration configuration, bool alwaysPersist)
		{
			try
			{
				if (configuration.Persistent || alwaysPersist)
				{
//					System.Diagnostics.Trace.WriteLine("Writing configuration '" + configuration.ElementName + "'");

					/// create an element for the category				
					XmlElement child = doc.CreateElement(@"Configuration");

					/// write the properties of this category
					child.SetAttribute(@"ElementName", configuration.ElementName);
					child.SetAttribute(@"HasChanges", XmlConvert.ToString(configuration.HasChanges));
					child.SetAttribute(@"Category", configuration.Category);
					child.SetAttribute(@"Description", configuration.Description);
					child.SetAttribute(@"DisplayName", configuration.DisplayName);
					child.SetAttribute(@"Hidden", XmlConvert.ToString(configuration.Hidden));
				
					/// append the child to our parent
					parent.AppendChild(child);

					this.WriteCategories(doc, child, configuration.Categories, alwaysPersist);
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Removes the specified configuration from the selected configurations diplayed by this control, optionally attempts to restore the location
		/// </summary>
		/// <param name="configuration"></param>
		/// <param name="keepLocationIfPossible"></param>
		public void RemoveConfiguration(XmlConfiguration configuration, bool keepLocationIfPossible)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new RemoveConfigurationInvoker(this.RemoveConfiguration), new object[] {configuration, keepLocationIfPossible});
				return;
			}

			try
			{
				if (configuration != null)
				{
					if (_selectedConfigurations.Contains(configuration))
					{
						string path = null;
						TreeNode n = _treeView.SelectedNode;
						if (n != null)
							path = n.FullPath;
						
						_selectedConfigurations.Remove(configuration);

						this.RefreshDisplay(path, keepLocationIfPossible);
					}
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Registers the file using the specified key in the specified configuration. If the key already exists, the file will be written to the existing key.
		/// </summary>
		/// <param name="configuration">The configuration in which the file will be registered</param>
		/// <param name="key">The key by which the file will be registered</param>
		/// <param name="filename">The filename that will be registered</param>
		/// <returns></returns>
		public static bool RegisterFile(XmlConfiguration configuration, string key, string filename)
		{
			ConfigurationEngine.ResetLastException();
			try
			{
				if (configuration != null)
				{
					if (key != null && key != string.Empty)
					{
						XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
						if (category != null)
						{	
							XmlConfigurationOption option = null;

							option = category.Options[key];
							if (option == null)
							{
								option = category.Options[key, true, filename];
								option.Category = @"Registered Files";
								option.Description = @"This indicates a configuration file that is registered and ready to be accessed via the ConfigurationEngine.";
							}
							option.Value = filename;
							return true;
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				_lastException = systemException;
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return false;
		}		
		/// <summary>
		/// Unregisters the file specified by the key supplied from the specified configuration
		/// </summary>
		/// <param name="configuration">The configuration in which the file will be unregistered</param>
		/// <param name="key">The key by which the file was originally registered</param>
		/// <returns></returns>
		public static bool UnregisterFile(XmlConfiguration configuration, string key)
		{
			ConfigurationEngine.ResetLastException();
			try
			{
				if (configuration != null)
				{
					if (key != null && key != string.Empty)
					{
						XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
						if (category != null)
						{	
							XmlConfigurationOption option = null;

							option = category.Options[key];
							if (option != null)
								category.Options.Remove(option);
							return true;
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				_lastException = systemException;
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return false;
		}		
		/// <summary>
		/// Writes a configuration to a path using the specified encryption engine. Takes windows security into account and checks for write access before trying to write to the path.
		/// </summary>
		/// <param name="path"></param>
		/// <param name="configuration"></param>
		/// <param name="encryptionEngine"></param>
		/// <returns></returns>
		public static bool WriteConfiguration(bool verbose, string path, XmlConfiguration configuration, FileEncryptionEngine encryptionEngine)
		{
			try
			{								
				Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' exists.");
				
				/// if the file exists, we need to try and read it
				if (System.IO.File.Exists(path))
				{
					Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' exists.");

					/// but first see if we have permissions to read it
					using(SecurityAccessRight right = new SecurityAccessRight(path))
					{
						Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' has write access.");

						/// if we don't have rights to the file						
						if (!right.AssertWriteAccess())
						{
							Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not have write access.");
							Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

							if (verbose)
							{
								/// prompt to see what we should do about this
								DialogResult result = ExceptionEngine.DisplayException(
									null,
									"Write access denied - Unable to write to file",
									MessageBoxIcon.Error,
									MessageBoxButtons.AbortRetryIgnore,
									null,
									"Write access has been denied for the file '" + path + "'.",
									"Ignoring this exception may result in a loss of data if any options in this file were changed.");

								switch(result)
								{							
								case DialogResult.Abort:
									Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to write to the path '" + path + "' because of user intervention.");
									return false;					

								case DialogResult.Retry:
									Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to write to the path '" + path + "' because of user intervention.");
									return ConfigurationEngine.WriteConfiguration(verbose, path, configuration, encryptionEngine);					

								case DialogResult.Ignore:
									Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to write to the path '" + path + "' because of user intervention.");
									return true;
									//break;					
								};												
							}
							else
							{
								/// it failed, but we're not in verbose mode so who cares?
								return true;
							}
						}
						else
						{
							Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' has write access, preparing to write the configuration.");

							/// rights to write to the file
							/// ask the configuration engine to write our configuration file for us into our configuration 
							if (!ConfigurationEngine.WriteConfiguration(encryptionEngine, configuration, path))
							{
								Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to write the configuration, throwing last exception from the ConfigurationEngine.");
								throw ConfigurationEngine.LastException;
							}
														
							/// ensure that the configuration has no changes visible
							if (configuration != null)
							{
								Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in writing the configuration, accepting changes .");
								configuration.AcceptChanges();
							}

							return true;
						}
					}
				}
				else
				{
					Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not exist, preparing to write the configuration for the first time.");
					
					/// ask the configuration engine to write our configuration file for us into our configuration 
					if (!ConfigurationEngine.WriteConfiguration(encryptionEngine, configuration, path))
					{
						Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to write the configuration, throwing last exception from the ConfigurationEngine.");
						throw ConfigurationEngine.LastException;
					}

					/// ensure that the configuration has no changes visible
					if (configuration != null)
					{
						Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in writing the configuration, accepting changes .");
						configuration.AcceptChanges();
					}

					return true;
				}
			}
			catch(System.Exception systemException)
			{
				Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while writing the configuration, dumping exception.");
				System.Diagnostics.Trace.WriteLine(systemException);
				Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

				if (verbose)
				{
					/// failed for some reason writing the file
					/// prompt to see what we should do about this
					DialogResult result = ExceptionEngine.DisplayException(
						null,					
						"Exception encountered - Unable to write to file",
						MessageBoxIcon.Error,
						MessageBoxButtons.AbortRetryIgnore,
						systemException,
						"An exception was encountered while trying to write to the file '" + path + "'.",
						"Ignoring this exception may result in a loss of data if any options in this file were changed");							

					switch(result)
					{							
					case DialogResult.Abort:	
						Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to write to the path '" + path + "' because of user intervention.");
						return false;					

					case DialogResult.Retry:
						Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to write to the path '" + path + "' because of user intervention.");
						return ConfigurationEngine.WriteConfiguration(verbose, path, configuration, encryptionEngine);					

					case DialogResult.Ignore:
						Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to write to the path '" + path + "' because of user intervention.");
						return true;			
					};
				}
			}				
			return true;
		}
		/// <summary>
		/// Reads or creates an XmlConfiguration from a name, path, and/or a handler function to provide structure to a new configuration.
		/// </summary>
		/// <param name="name">The name that will be given to the configuration</param>
		/// <param name="path">The path to the file where the configuration is stored</param>
		/// <param name="configuration">The configuration that will be returned after creation or reading has finished</param>
		/// <param name="encryptionEngine">The encryption engine to use when reading the file</param>
		/// <param name="handler">The event handler to call if structure is needed for a new configuration</param>
		/// <returns>True if a configuration was created or read</returns>
		public static bool ReadOrCreateConfiguration(
			bool verbose,
			string name,
			string path, 
			out XmlConfiguration configuration, 
			FileEncryptionEngine encryptionEngine, 
			XmlConfigurationEventHandler handler)
		{
			configuration = null;

			Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' exists.");

			/// if the file exists, we need to try and read it
			if (System.IO.File.Exists(path))
			{	
				Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' exists.");

				try
				{
					/// but first see if we have permissions to read it
					using(SecurityAccessRight right = new SecurityAccessRight(path))
					{
						Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' has read access.");

						/// if we don't have rights to the file
						if (!right.AssertReadAccess())
						{
							Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not have write access.");
							Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

							/// prompt to see what we should do about this
							DialogResult result = ExceptionEngine.DisplayException(
								null,
								"Read access denied - Unable to read from file",
								MessageBoxIcon.Error,
								MessageBoxButtons.AbortRetryIgnore,
								null,
								"Read access has been denied for the '" + name + "'.",
								"Ignoring this exception will result in a default set of options to be loaded in the '" + name + "' for this application instance.",					
								"If the file has write access enabled, it will be overwritten with the loaded options when the application exits.",					
								"WARNING: Aborting this operation will exit the application!");

							switch(result)
							{							
							case DialogResult.Abort:	
								Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to read from the path '" + path + "' because of user intervention.");
								return false;					

							case DialogResult.Retry:
								Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to read from the path '" + path + "' because of user intervention.");
								return ConfigurationEngine.ReadOrCreateConfiguration(verbose, name, path, out configuration, encryptionEngine, handler);					

							case DialogResult.Ignore:
								Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to read from the path '" + path + "' because of user intervention.");
								return true;
								//break;					
							};												
						}
						else
						{
							Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' has read access, preparing to read the configuration.");

							/// rights to read the file
							/// ask the configuration engine to read our configuration file for us into our configuration 
							if (!ConfigurationEngine.ReadConfiguration(encryptionEngine, out configuration, path))
							{
								Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to read the configuration, throwing last exception from the ConfigurationEngine.");
								throw ConfigurationEngine.LastException;
							}

							/// let the configuration know where it lives							
							//							configuration.Path = path;

							/// ensure that the configuration has no changes visible
							if (configuration != null)
							{
								Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in reading the configuration, accepting changes .");
								configuration.AcceptChanges();
							}

							return true;
						}
					}
				}
				catch(System.Exception systemException)
				{
					Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while reading the configuration, dumping exception.");
					System.Diagnostics.Trace.WriteLine(systemException);
					Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

					/// failed for some reason reading the file
					/// prompt to see what we should do about this
					DialogResult result = ExceptionEngine.DisplayException(
						null,					
						"Exception encountered - Unable to read from file",
						MessageBoxIcon.Error,
						MessageBoxButtons.AbortRetryIgnore,
						systemException,
						"An exception was encountered while trying to read '" + name + "'.",
						"Ignoring this exception will result in a default set of options to be loaded in the '" + name + "' for this application instance.",					
						"If the file has write access enabled, it will be overwritten with the loaded options when the application exits.",					
						"WARNING: Aborting this operation will exit the application!");

					switch(result)
					{							
					case DialogResult.Abort:	
						Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to read from the path '" + path + "' because of user intervention.");
						return false;					

					case DialogResult.Retry:
						Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to read from the path '" + path + "' because of user intervention.");
						return ConfigurationEngine.ReadOrCreateConfiguration(verbose, name, path, out configuration, encryptionEngine, handler);					

					case DialogResult.Ignore:
						Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to read from the path '" + path + "' because of user intervention.");
						break;			
					};
				}				
			}
			else
			{
				Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not exist.");
			}

			/// if for some reason the configuration hasn't been loaded yet
			if (configuration == null)
			{
				Trace.WriteLineIf(verbose, "'Configuration Engine': Creating new configuration named '" + name + "'.");
				configuration = new XmlConfiguration();
				configuration.ElementName = name;

				Trace.WriteLineIf(verbose, "'Configuration Engine': Checking for formatting callback for the configuration named '" + name + "'.");

				if (handler != null)
				{
					Trace.WriteLineIf(verbose, "'Configuration Engine': Formatting callback found for the configuration named '" + name + "', calling formatting callback to apply structure to the configuration.");
					try
					{
						XmlConfigurationEventArgs e = new XmlConfigurationEventArgs(configuration, XmlConfigurationElementActions.None);
						handler(null, e);
						configuration = e.Element;
					}
					catch(System.Exception systemException)
					{
						Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while reading the configuration named '" + name + "', dumping exception.");
						System.Diagnostics.Trace.WriteLine(systemException);
					}
				}
			}
									
			Trace.WriteLineIf(verbose, "'Configuration Engine': Setting the path for the configuration named '" + name + "' and accepting changes to the configuration.");

			/// let the configuration know where it lives
			configuration.Path = path;

			/// ensure that the configuration has no changes visible
			configuration.AcceptChanges();

			return true;
		}
		/// <summary>
		/// Reads a configuration using the specified encryption engine from the specified path
		/// </summary>
		/// <param name="encryptionEngine">The encryption engine to use while reading the configuration, null if no decryption is desired</param>
		/// <param name="configuration">The configuration to be read into</param>
		/// <param name="path">The path to be read from</param>
		/// <returns></returns>
		public static bool ReadConfiguration(FileEncryptionEngine encryptionEngine, out XmlConfiguration configuration, string path)
		{
			Stream stream = null;
			ConfigurationEngine.ResetLastException();
			try
			{
				configuration = new XmlConfiguration();		
				stream = (encryptionEngine != null ? encryptionEngine.CreateDecryptorStream(path) : new FileStream(path, FileMode.Open, FileAccess.Read , FileShare.None));
				XmlConfigurationReader reader = new XmlConfigurationReader();
				configuration = reader.Read(stream);		
				configuration.Path = path;
				configuration.SetHasUnpersistedChanges(false);

				return true;	
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
				_lastException = systemException;
			}
			finally
			{
				try 
				{
					if (stream != null) stream.Close();
				}
				catch { }
			}
			configuration = null;
			return false;
		}
		/// <summary>
		/// Creates an installation record for the specified Type
		/// </summary>
		/// <param name="configuration">The configuration in which the category will be created</param>
		/// <param name="type">The type for which the category will be created</param>
		/// <returns></returns>
		public static XmlConfigurationCategory InstallVersionOfType(XmlConfiguration configuration, Type type, out DateTime installDate)
		{
			installDate = DateTime.Now;

			// remove the uninstall entry for the type
			InstallationEngine.RemoveUninstalledEntryForType(configuration, type);

			// create the install entry for the type
			XmlConfigurationCategory category = InstallationEngine.CreateCategoryForTypeVersion(configuration, type, CategoryNames.Installed);
			if (category != null)
			{
				XmlConfigurationOption option = null;

				// create the install date 
				option = category.Options[@"InstallDate"];
				if (option == null)
				{					
					option = category.Options[@"InstallDate", true, installDate];
					option.Category = @"Installation Notes";
					option.Description = @"This date marks the date and time on which the SnapIn was installed.";
					option.ShouldSerializeValue = true;
				}
				option = null;
				
				// create the run count
				option = category.Options[@"RunCount"];
				if (option == null)
				{
					option = category.Options[@"RunCount", true, 0];
					option.Category = @"Installation Notes";
					option.Description = @"This number indicates the number of times the SnapIn has executed.";
				}
				option = null;
			}
			return category;
		}
		public static bool RemoveUninstalledEntryForType(XmlConfiguration configuration, Type type)
		{
			XmlConfigurationCategory category = null;
			
			// find and remove the install category for this type
			category = InstallationEngine.GetExistingCategoryForTypeVersion(configuration, type, CategoryNames.Uninstalled);
			if (category != null)
			{
				category.Remove();
				category = null;
			}
			return true;
		}
		/// <summary>
		/// Attempts to increment the RunCount option for the specified version of the specified Type
		/// </summary>
		/// <param name="configuration">The configuration in which the option will be found</param>
		/// <param name="type">The Type for which the RunCount value will be incremented</param>
		/// <returns></returns>
		public static bool IncrementRunCountForVersionOfType(XmlConfiguration configuration, Type type, out DateTime installDate, out int runCount)
		{
			installDate = DateTime.Now;
			runCount = 0;
			try
			{
				XmlConfigurationCategory category = InstallationEngine.GetExistingCategoryForTypeVersion(configuration, type, CategoryNames.Installed);
				if (category != null)
				{
					XmlConfigurationOption option = null;
					
					option = category.Options[@"InstallDate"];
					if (option != null)
					{
						installDate = (DateTime)option.Value;
					}

					option = category.Options[@"RunCount"];
					if (option != null)
					{
						// retrieve, increment, and set the run count
						runCount = (int)option.Value;
						runCount++; 
						option.Value = runCount;												
					}
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}	
			return false;
		}
		/// <summary>
		/// Returns the filename using the specified key from the specified configuration 
		/// </summary>
		/// <param name="configuration">The configuration from which the filename will be extracted</param>
		/// <param name="key">The key by which the filename was saved</param>
		/// <returns></returns>
		public static string GetRegisteredFilename(XmlConfiguration configuration, string key)
		{
			ConfigurationEngine.ResetLastException();
			try
			{
				if (configuration != null)
				{
					if (key != null && key != string.Empty)
					{
						XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
						if (category != null)
						{	
							XmlConfigurationOption option = null;

							option = category.Options[key];
							if (option != null)
								return (string)option.Value;
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				_lastException = systemException;
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return string.Empty;
		}
		/// <summary>
		/// Writes an entire configuration file using the specified configuration and stream.
		/// </summary>
		/// <param name="configuration"></param>
		/// <param name="stream"></param>
		/// <param name="alwaysPersist"></param>
		public void Write(XmlConfiguration configuration, Stream stream, bool alwaysPersist)
		{
			try
			{
				/// create a new xml document
				XmlDocument doc = new XmlDocument();

				/// create the root element
				XmlElement root = doc.CreateElement(@"ConfigurationFile");
				
				/// append the root element as the first element
				doc.AppendChild(root);
								
				/// mark the xml as version 1.0 compliant
				XmlDeclaration versionDeclaration = doc.CreateXmlDeclaration(@"1.0", null, null);
				
				/// insert the version element as the first element
				doc.InsertBefore(versionDeclaration, root);
				
				this.WriteConfiguration(doc, root, configuration, alwaysPersist);
																
				/// save the xml document to the stream
				doc.Save(stream);
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.Write(systemException);
			}
		}
		/// <summary>
		/// Returns a Hashtable containing the key and filename of each file that is registered in the specified configuration
		/// </summary>
		/// <param name="configuration">The configuration in which the search will occur</param>
		/// <returns></returns>
		public static Hashtable GetRegisteredFiles(XmlConfiguration configuration)
		{
			ConfigurationEngine.ResetLastException();
			try
			{
				if (configuration != null)
				{
					XmlConfigurationCategory category = configuration.Categories[CategoryNames.Files.ToString()];
					if (category != null)
					{	
						Hashtable table = new Hashtable();
						foreach(XmlConfigurationOption option in category.Options)
							table.Add(option.ElementName, (string)option.Value);
						return table;
					}
				}
			}
			catch(System.Exception systemException)
			{
				_lastException = systemException;
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return new Hashtable();
		}
		/// <summary>
		/// Adds the specified configuration to the selected configurations displayed by this control
		/// </summary>
		/// <param name="configuration"></param>
		public void AddConfiguration(XmlConfiguration configuration)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new AddConfigurationInvoker(this.AddConfiguration), new object[] {configuration});
				return;
			}

			try
			{
				if (configuration != null)
				{				
					configuration.Changed += new XmlConfigurationElementEventHandler(OnConfigurationChanged);
					if (_placeElementsIntoEditMode)
						configuration.BeginEdit();		
					_selectedConfigurations.Add(configuration);		
					this.AddNodesForCategories(_treeView, null, configuration.Categories);							
					this.AddXmlTabForConfiguration(configuration);
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Creates a category for the type including it's version (defaulted to "1.0.0.0" for versionless types) in the specified configuration, using the specified type, and specified category name.
		/// </summary>
		/// <param name="configuration">The configuration in which the category will be created</param>
		/// <param name="type">The type for which the category will be created</param>
		/// <param name="categoryName">The category name in which creation will occur</param>
		/// <returns></returns>
		public static XmlConfigurationCategory CreateCategoryForTypeVersion(XmlConfiguration configuration, Type type, CategoryNames categoryName)
		{
			try
			{
				if (configuration != null)
				{					
					if (type != null)
					{
						// start in the specified category
						XmlConfigurationCategory searchCategory = configuration.Categories[@"SnapIns\" + categoryName.ToString()];
						if (searchCategory != null)
						{
							SnapInAttributeReader reader = new SnapInAttributeReader(type);
							if (reader != null)
							{
								Version version = null;
								SnapInVersionAttribute versionAttribute = reader.GetSnapInVersionAttribute();
								if (versionAttribute != null)
									version = versionAttribute.Version;
								else
									version = new Version(1, 0, 0, 0);
								
								string path = string.Format("{0}\\{1}\\{2}", @"SnapIns\" + categoryName.ToString(), type.FullName, version.ToString());
								return configuration.Categories[path, true];
							}
						}
					}
				}
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
			return null;
		}
		/// <summary>
		/// Adds an Xml tab for the specified configuration
		/// </summary>
		/// <param name="configuration"></param>
		private void AddXmlTabForConfiguration(XmlConfiguration configuration)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new AddXmlTabForConfigurationInvoker(this.AddXmlTabForConfiguration), new object[] {configuration});
				return;
			}

			try
			{
				this.tabControlXmlViews.SuspendLayout();

				XmlConfigurationXmlBehindViewer view = new XmlConfigurationXmlBehindViewer();
				view.Xml = configuration.ToXml();

				TabPage page = new TabPage(configuration.ElementName);
				page.Controls.Add(view);
				view.Parent = page;
				view.Dock = DockStyle.Fill;
				
				this.tabControlXmlViews.TabPages.Add(page);				
				this.tabControlXmlViews.ResumeLayout(true);
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}
		}
		/// <summary>
		/// Parses the "Uninstalled" category in the configuration specified for the type specified, and returns an array of Versions for each Version of the Type that is listed as "Uninstalled"
		/// </summary>
		/// <param name="configuration">The configuration to parse</param>
		/// <param name="type">The type to search for</param>
		/// <returns></returns>
		public static Version[] GetUninstalledVersionsOfType(XmlConfiguration configuration, Type type)
		{
			return InstallationEngine.GetListedVersionsOfType(configuration, type, CategoryNames.Uninstalled);
		}
        /// <summary>
        /// Writes a configuration to a path using the specified encryption engine. Takes windows security into account and checks for write access before trying to write to the path.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="configuration"></param>
        /// <param name="encryptionEngine"></param>
        /// <returns></returns>
        public static bool WriteConfiguration(bool verbose, string path, XmlConfiguration configuration, FileEncryptionEngine encryptionEngine)
        {
            try
            {
                Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' exists.");

                /// if the file exists, we need to try and read it
                if (System.IO.File.Exists(path))
                {
                    Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' exists.");

                    /// but first see if we have permissions to read it
                    using (SecurityAccessRight right = new SecurityAccessRight(path))
                    {
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' has write access.");

                        /// if we don't have rights to the file
                        if (!right.AssertWriteAccess())
                        {
                            Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not have write access.");
                            Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

                            if (verbose)
                            {
                                /// prompt to see what we should do about this
                                DialogResult result = ExceptionEngine.DisplayException(
                                    null,
                                    "Write access denied - Unable to write to file",
                                    MessageBoxIcon.Error,
                                    MessageBoxButtons.AbortRetryIgnore,
                                    null,
                                    "Write access has been denied for the file '" + path + "'.",
                                    "Ignoring this exception may result in a loss of data if any options in this file were changed.");

                                switch (result)
                                {
                                case DialogResult.Abort:
                                    Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to write to the path '" + path + "' because of user intervention.");
                                    return(false);

                                case DialogResult.Retry:
                                    Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to write to the path '" + path + "' because of user intervention.");
                                    return(ConfigurationEngine.WriteConfiguration(verbose, path, configuration, encryptionEngine));

                                case DialogResult.Ignore:
                                    Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to write to the path '" + path + "' because of user intervention.");
                                    return(true);
                                    //break;
                                }
                                ;
                            }
                            else
                            {
                                /// it failed, but we're not in verbose mode so who cares?
                                return(true);
                            }
                        }
                        else
                        {
                            Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' has write access, preparing to write the configuration.");

                            /// rights to write to the file
                            /// ask the configuration engine to write our configuration file for us into our configuration
                            if (!ConfigurationEngine.WriteConfiguration(encryptionEngine, configuration, path))
                            {
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to write the configuration, throwing last exception from the ConfigurationEngine.");
                                throw ConfigurationEngine.LastException;
                            }

                            /// ensure that the configuration has no changes visible
                            if (configuration != null)
                            {
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in writing the configuration, accepting changes .");
                                configuration.AcceptChanges();
                            }

                            return(true);
                        }
                    }
                }
                else
                {
                    Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not exist, preparing to write the configuration for the first time.");

                    /// ask the configuration engine to write our configuration file for us into our configuration
                    if (!ConfigurationEngine.WriteConfiguration(encryptionEngine, configuration, path))
                    {
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to write the configuration, throwing last exception from the ConfigurationEngine.");
                        throw ConfigurationEngine.LastException;
                    }

                    /// ensure that the configuration has no changes visible
                    if (configuration != null)
                    {
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in writing the configuration, accepting changes .");
                        configuration.AcceptChanges();
                    }

                    return(true);
                }
            }
            catch (System.Exception systemException)
            {
                Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while writing the configuration, dumping exception.");
                System.Diagnostics.Trace.WriteLine(systemException);
                Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

                if (verbose)
                {
                    /// failed for some reason writing the file
                    /// prompt to see what we should do about this
                    DialogResult result = ExceptionEngine.DisplayException(
                        null,
                        "Exception encountered - Unable to write to file",
                        MessageBoxIcon.Error,
                        MessageBoxButtons.AbortRetryIgnore,
                        systemException,
                        "An exception was encountered while trying to write to the file '" + path + "'.",
                        "Ignoring this exception may result in a loss of data if any options in this file were changed");

                    switch (result)
                    {
                    case DialogResult.Abort:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to write to the path '" + path + "' because of user intervention.");
                        return(false);

                    case DialogResult.Retry:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to write to the path '" + path + "' because of user intervention.");
                        return(ConfigurationEngine.WriteConfiguration(verbose, path, configuration, encryptionEngine));

                    case DialogResult.Ignore:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to write to the path '" + path + "' because of user intervention.");
                        return(true);
                    }
                    ;
                }
            }
            return(true);
        }
Example #49
0
        protected override XmlConfigurationElement GetElementToEdit()
        {
            XmlConfiguration configuration = (XmlConfiguration)this.Clone();

            return((XmlConfigurationElement)configuration);
        }
		public void AddConfiguration(XmlConfiguration configuration)
		{
			_xmlConfigurationView.AddConfiguration(configuration);
		}
 public XmlConfigurationEventArgs(XmlConfiguration configuration, XmlConfigurationElementActions action) : base(configuration, action)
 {
 }
		/// <summary>
		/// Reads an XmlConfiguration from a System.IO.Stream
		/// </summary>
		/// <param name="stream">The stream that contains the XmlConfiguration file</param>
		/// <returns></returns>
		public XmlConfiguration Read(Stream stream)
		{
			try
			{
				// create a new xml document
				XmlDocument doc = new XmlDocument();
				
				// load it from the stream
				doc.Load(stream);

				// create a new xpath navigator so that we can traverse the elements inside the xml
				XPathNavigator navigator = doc.CreateNavigator();
				
				// move to the version element
				navigator.MoveToFirstChild(); 

				// move to the file format description element
				navigator.MoveToNext();						

				// create a new configuration
				XmlConfiguration configuration = new XmlConfiguration();
				
				// begin initialization so that events do not fire inside the configuration
				configuration.BeginInit();

				// using the xpath navigator, read the xml document and turn it into a configuration
				this.ReadConfiguration(navigator, configuration);
				
				// end initialization
				configuration.EndInit();

				return configuration;
			}
			catch(System.Exception systemException)
			{
				System.Diagnostics.Trace.WriteLine(systemException);
			}		
			return null;
		}
        /// <summary>
        /// Reads or creates an XmlConfiguration from a name, path, and/or a handler function to provide structure to a new configuration.
        /// </summary>
        /// <param name="name">The name that will be given to the configuration</param>
        /// <param name="path">The path to the file where the configuration is stored</param>
        /// <param name="configuration">The configuration that will be returned after creation or reading has finished</param>
        /// <param name="encryptionEngine">The encryption engine to use when reading the file</param>
        /// <param name="handler">The event handler to call if structure is needed for a new configuration</param>
        /// <returns>True if a configuration was created or read</returns>
        public static bool ReadOrCreateConfiguration(
            bool verbose,
            string name,
            string path,
            out XmlConfiguration configuration,
            FileEncryptionEngine encryptionEngine,
            XmlConfigurationEventHandler handler)
        {
            configuration = null;

            Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' exists.");

            /// if the file exists, we need to try and read it
            if (System.IO.File.Exists(path))
            {
                Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' exists.");

                try
                {
                    /// but first see if we have permissions to read it
                    using (SecurityAccessRight right = new SecurityAccessRight(path))
                    {
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Checking to see if the path '" + path + "' has read access.");

                        /// if we don't have rights to the file
                        if (!right.AssertReadAccess())
                        {
                            Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not have write access.");
                            Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

                            /// prompt to see what we should do about this
                            DialogResult result = ExceptionEngine.DisplayException(
                                null,
                                "Read access denied - Unable to read from file",
                                MessageBoxIcon.Error,
                                MessageBoxButtons.AbortRetryIgnore,
                                null,
                                "Read access has been denied for the '" + name + "'.",
                                "Ignoring this exception will result in a default set of options to be loaded in the '" + name + "' for this application instance.",
                                "If the file has write access enabled, it will be overwritten with the loaded options when the application exits.",
                                "WARNING: Aborting this operation will exit the application!");

                            switch (result)
                            {
                            case DialogResult.Abort:
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to read from the path '" + path + "' because of user intervention.");
                                return(false);

                            case DialogResult.Retry:
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to read from the path '" + path + "' because of user intervention.");
                                return(ConfigurationEngine.ReadOrCreateConfiguration(verbose, name, path, out configuration, encryptionEngine, handler));

                            case DialogResult.Ignore:
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to read from the path '" + path + "' because of user intervention.");
                                return(true);
                                //break;
                            }
                            ;
                        }
                        else
                        {
                            Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' has read access, preparing to read the configuration.");

                            /// rights to read the file
                            /// ask the configuration engine to read our configuration file for us into our configuration
                            if (!ConfigurationEngine.ReadConfiguration(encryptionEngine, out configuration, path))
                            {
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Failed to read the configuration, throwing last exception from the ConfigurationEngine.");
                                throw ConfigurationEngine.LastException;
                            }

                            /// let the configuration know where it lives
                            //							configuration.Path = path;

                            /// ensure that the configuration has no changes visible
                            if (configuration != null)
                            {
                                Trace.WriteLineIf(verbose, "'Configuration Engine': Succeeded in reading the configuration, accepting changes .");
                                configuration.AcceptChanges();
                            }

                            return(true);
                        }
                    }
                }
                catch (System.Exception systemException)
                {
                    Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while reading the configuration, dumping exception.");
                    System.Diagnostics.Trace.WriteLine(systemException);
                    Trace.WriteLineIf(verbose, "'Configuration Engine': Prompting for user intervention for the path '" + path + "'.");

                    /// failed for some reason reading the file
                    /// prompt to see what we should do about this
                    DialogResult result = ExceptionEngine.DisplayException(
                        null,
                        "Exception encountered - Unable to read from file",
                        MessageBoxIcon.Error,
                        MessageBoxButtons.AbortRetryIgnore,
                        systemException,
                        "An exception was encountered while trying to read '" + name + "'.",
                        "Ignoring this exception will result in a default set of options to be loaded in the '" + name + "' for this application instance.",
                        "If the file has write access enabled, it will be overwritten with the loaded options when the application exits.",
                        "WARNING: Aborting this operation will exit the application!");

                    switch (result)
                    {
                    case DialogResult.Abort:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Aborting attempt to read from the path '" + path + "' because of user intervention.");
                        return(false);

                    case DialogResult.Retry:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Retrying attempt to read from the path '" + path + "' because of user intervention.");
                        return(ConfigurationEngine.ReadOrCreateConfiguration(verbose, name, path, out configuration, encryptionEngine, handler));

                    case DialogResult.Ignore:
                        Trace.WriteLineIf(verbose, "'Configuration Engine': Ignoring attempt to read from the path '" + path + "' because of user intervention.");
                        break;
                    }
                    ;
                }
            }
            else
            {
                Trace.WriteLineIf(verbose, "'Configuration Engine': The path '" + path + "' does not exist.");
            }

            /// if for some reason the configuration hasn't been loaded yet
            if (configuration == null)
            {
                Trace.WriteLineIf(verbose, "'Configuration Engine': Creating new configuration named '" + name + "'.");
                configuration             = new XmlConfiguration();
                configuration.ElementName = name;

                Trace.WriteLineIf(verbose, "'Configuration Engine': Checking for formatting callback for the configuration named '" + name + "'.");

                if (handler != null)
                {
                    Trace.WriteLineIf(verbose, "'Configuration Engine': Formatting callback found for the configuration named '" + name + "', calling formatting callback to apply structure to the configuration.");
                    try
                    {
                        XmlConfigurationEventArgs e = new XmlConfigurationEventArgs(configuration, XmlConfigurationElementActions.None);
                        handler(null, e);
                        configuration = e.Element;
                    }
                    catch (System.Exception systemException)
                    {
                        Trace.WriteLineIf(verbose, "'Configuration Engine': An unexpected exception was encountered while reading the configuration named '" + name + "', dumping exception.");
                        System.Diagnostics.Trace.WriteLine(systemException);
                    }
                }
            }

            Trace.WriteLineIf(verbose, "'Configuration Engine': Setting the path for the configuration named '" + name + "' and accepting changes to the configuration.");

            /// let the configuration know where it lives
            configuration.Path = path;

            /// ensure that the configuration has no changes visible
            configuration.AcceptChanges();

            return(true);
        }
		/// <summary>
		/// Reads a configuration using the specified XPathNavigator
		/// </summary>
		/// <param name="navigator"></param>
		/// <returns></returns>
		private XmlConfiguration ReadConfiguration(XPathNavigator navigator, XmlConfiguration configuration)
		{
			if (navigator.MoveToFirstChild())
			{
				if (string.Compare(navigator.Name, @"Configuration", true) == 0)
				{
					// does the cateogry have attributes, it should!
					if (navigator.HasAttributes)
					{
						// break off yet another clone to navigate the attributes of this element
						XPathNavigator attributesNavigator = navigator.Clone();
						if (attributesNavigator.MoveToFirstAttribute())
						{
							configuration.ElementName = attributesNavigator.Value;

							while(attributesNavigator.MoveToNextAttribute())
							{
								switch(attributesNavigator.Name)
								{
								case @"HasChanges":
									configuration.HasChanges = XmlConvert.ToBoolean(attributesNavigator.Value);
									break;
								case @"Category":
									configuration.Category = attributesNavigator.Value;
									break;
								case @"Description":
									configuration.Description = attributesNavigator.Value;
									break;
								case @"DisplayName":
									configuration.DisplayName = attributesNavigator.Value;
									break;
								case @"Hidden":
									configuration.Hidden = XmlConvert.ToBoolean(attributesNavigator.Value);
									break;
								};						
							}
						}
					}
				}
			}

			// recursively read the categories within this configuration file
			this.ReadCategories(navigator, configuration.Categories);

			return configuration;
		}
Example #55
0
 /// <summary>
 /// Initializes a new instance of the XmlConfigurationOption class
 /// </summary>
 /// <param name="option">The option to base this option on</param>
 public XmlConfiguration(XmlConfiguration configuration) : base((XmlConfigurationElement)configuration)
 {
     _path       = configuration.Path;
     _categories = configuration.Categories;
 }
Example #56
0
 public void RemoveConfiguration(XmlConfiguration configuration, bool keepLocationIfPossible)
 {
     _xmlConfigurationView.RemoveConfiguration(configuration, keepLocationIfPossible);
 }
		/// <summary>
		/// Creates an uninstallation record for the specified Type
		/// </summary>
		/// <param name="configuration">The configuration in which the category will be created</param>
		/// <param name="type">The type for which the category will be created</param>
		/// <returns></returns>
		public static XmlConfigurationCategory UninstallVersionOfType(XmlConfiguration configuration, Type type)
		{
			// remove the install entry for the type
			InstallationEngine.RemoveInstalledEntryForType(configuration, type);

			// create the uninstall entry for the type
			XmlConfigurationCategory category = InstallationEngine.CreateCategoryForTypeVersion(configuration, type, CategoryNames.Uninstalled);
			if (category != null)
			{
				XmlConfigurationOption option = null;

				// create the install date 
				option = category.Options[@"UninstallDate"];
				if (option == null)
				{
					option = category.Options[@"UninstallDate", true, DateTime.Now.ToString()];
					option.Category = @"Installation Notes";
					option.Description = @"This date marks the date and time on which the SnapIn was uninstalled.";
				}
				option = null;
			}
			return category;
		}