651 lines · 27.3 KB · C#
RawDownload
//******************************************************************************************************//  ConfigurationFile.cs - Gbtc////  Copyright © 2012, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  04/12/2006 - Pinal C. Patel//       Generated original version of source code.//  11/14/2006 - Pinal C. Patel//       Modified the ValidateConfigurationFile to save the config file only it was modified.//  12/12/2006 - Pinal C. Patel//       Wrote the TrimEnd function that is being used for initialized the Configuration object.//  08/20/2007 - Darrell Zuercher//       Edited code comments.//  09/22/2008 - Pinal C. Patel//       Converted code to C#.//  09/29/2008 - Pinal C. Patel//       Reviewed code comments.//  09/14/2009 - Stephen C. Wills//       Added new header and license agreement.//  09/29/2008 - Pinal C. Patel//       Added new CurrentWeb and CurrentWin static properties to get the configuration file for a //       specific type of application (i.e. Web or Windows).//       Modified GetConfiguration() to remove dependency on HttpContext.Current to avoid exception in//       async web application operations where HttpContext.Current is null.//  04/20/2010 - Pinal C. Patel//       Added static Open() method as the only way of retrieving a ConfigurationFile instance.//       Added internal UserConfigurationFile class for accessing and updating user scope settings.//  07/01/2010 - Pinal C. Patel//       Removed FileName, AppSettings and ConnectionStrings proxy properties and replaced them with//       new Configuration property to allow for full access to the application configuration.//  11/26/2010 - Pinal C. Patel//       Updated usage example to include user-scope setting sample.//  12/05/2010 - Pinal C. Patel//       Added Culture property that can be used for specifying a culture to use for value conversion.//  01/04/2011 - J. Ritchie Carroll//       Modified culture to default to InvariantCulture for English style parsing defaults.//  04/07/2011 - J. Ritchie Carroll//       Added a Reload() method to reload the configuration file settings and a//       RestoreDefaultUserSettings() method to restore the default user settings.//  12/12/2011 - J. Ritchie Carroll//       Added synchronization to save methods such that saves from multiple threads will not//       cause issues when lots of new settings are being added.//  12/14/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using System;using System.Collections.Concurrent;using System.Configuration;using System.Globalization;using System.IO;using System.Text;using System.Web.Configuration;using System.Web.Hosting;using System.Xml;using GSF.IO;using GSF.Threading;using GSF.Xml; namespace GSF.Configuration{    /// <summary>    /// Represents a configuration file of a Windows or Web application.    /// </summary>    /// <example>    /// This example shows how to save and read settings from the config file:    /// <code>    /// using System;    /// using System.Configuration;    /// using GSF;    /// using GSF.Configuration;    ///     /// class Program    /// {    ///     static void Main(string[] args)    ///     {    ///         // Get the application config file.    ///         ConfigurationFile config = ConfigurationFile.Current;    ///     ///         // Get the sections of config file.    ///         CategorizedSettingsElementCollection startup = config.Settings["Startup"];    ///         CategorizedSettingsElementCollection passwords = config.Settings["Passwords"];    ///         CategorizedSettingsElementCollection monitoring = config.Settings["Monitoring"];    ///         KeyValueConfigurationCollection appSettings = config.Configuration.AppSettings.Settings;    ///         ConnectionStringSettingsCollection connStrings = config.Configuration.ConnectionStrings.ConnectionStrings;    ///     ///         // Add settings to the config file under the "appSettings" section.    ///         appSettings.Add("SaveSettingOnExit", true.ToString());    ///         // Add settings to the config file under the "connectionStrings" section.    ///         connStrings.Add(new ConnectionStringSettings("DevSql", "Server=SqlServer;Database=Sandbox;Trusted_Connection=True"));    ///         // Add settings to the config (if they don't exist) under a custom "monitoring" section.    ///         monitoring.Add("RefreshInterval", 5, "Interval in seconds at which the Monitor screen is to be refreshed.");    ///         monitoring.Add("MessagesSnapshot", 30000, "Maximum messages length to be displayed on the Monitor screen.");    ///         // Add password to the config file encrypted (if it doesn't exist) under a custom "passwords" section.    ///         passwords.Add("Admin", "Adm1nP4ss", "Password used for performing administrative tasks.", true);    ///         // Add user-scope setting to the config (if it doesn't exist) under a custom "startup" section.    ///         startup.Add("Theme", "Default", "Application theme to use for the session.", false, SettingScope.User);    ///         config.Save();  // Save settings to the config file.    ///     ///         // Read saved settings from the config file.    ///         bool saveSettingsOnExit = appSettings["SaveSettingOnExit"].Value.ParseBoolean();    ///         string devConnectionString = connStrings["DevSql"].ConnectionString;    ///         string appTheme = startup["Theme"].Value;    ///         string adminPassword = passwords["Admin"].Value;    ///         int refreshInterval = monitoring["RefreshInterval"].ValueAsInt32();    ///         int messagesSnapshot = monitoring["MessagesSnapshot"].ValueAsInt32();    ///     ///         // Print the retrieved settings to the console.    ///         Console.WriteLine("SaveSettingOnExit = {0}", saveSettingsOnExit);    ///         Console.WriteLine("DevSql = {0}", devConnectionString);    ///         Console.WriteLine("Theme = {0}", appTheme);    ///         Console.WriteLine("Admin = {0}", adminPassword);    ///         Console.WriteLine("RefreshInterval = {0}", refreshInterval);    ///         Console.WriteLine("MessagesSnapshot = {0}", messagesSnapshot);    ///     ///         Console.ReadLine();    ///     }    /// }    /// </code>    /// This example shows the content of the config file from the sample code above:    /// <code>    /// <![CDATA[    /// <?xml version="1.0" encoding="utf-8"?>    /// <configuration>    ///   <configSections>    ///     <section name="categorizedSettings" type="GSF.Configuration.CategorizedSettingsSection, GSF.Core" />    ///   </configSections>    ///   <appSettings>    ///     <add key="SaveSettingOnExit" value="True" />    ///   </appSettings>    ///   <categorizedSettings>    ///     <startup>    ///       <add name="Theme" value="Default" description="Application theme to use for the session."    ///         encrypted="false" scope="User" />    ///     </startup>    ///     <passwords>    ///       <add name="Admin" value="C+0j6fE/N0Q9b5xaeDKgvRmSeY9zJkO1EQCr7cHoG3x24tztlbBB54PfWsuMGXc/"    ///         description="Password used for performing administrative tasks."    ///         encrypted="true" />    ///     </passwords>    ///     <monitoring>    ///       <add name="RefreshInterval" value="5" description="Interval in seconds at which the Monitor screen is to be refreshed."    ///         encrypted="false" />    ///       <add name="MessagesSnapshot" value="30000" description="Maximum messages length to be displayed on the Monitor screen."    ///         encrypted="false" />    ///     </monitoring>    ///   </categorizedSettings>    ///   <connectionStrings>    ///     <add name="DevSql" connectionString="Server=SqlServer;Database=Sandbox;Trusted_Connection=True" />    ///   </connectionStrings>    /// </configuration>    /// ]]>    /// </code>    /// </example>    /// <seealso cref="CategorizedSettingsSection"/>    /// <seealso cref="CategorizedSettingsElement"/>    /// <seealso cref="CategorizedSettingsElementCollection"/>    // Since each instance of this class is statically cached for the process lifetime, IDisposable is not implemented so that    // the instance will not be inadvertently disposed    public class ConfigurationFile    {        #region [ Members ]         // Nested Types        internal class UserConfigurationFile        {            private readonly string m_fileName;            private readonly XmlDocument m_settings;            private bool m_settingsModified;             private const string RootNode = "settings";            private const string Filename = "Settings.xml";             public UserConfigurationFile()            {                m_settings = new XmlDocument();                m_fileName = Path.Combine(FilePath.GetApplicationDataFolder(), Filename);                 if (File.Exists(m_fileName))                {                    try                    {                        // Load existing settings.                        m_settings.Load(m_fileName);                    }                    catch (Exception)                    {                        // Create new settings file.                        m_settings.AppendChild(m_settings.CreateNode(XmlNodeType.XmlDeclaration, null, null));                        m_settings.AppendChild(m_settings.CreateElement(RootNode));                    }                }                else                {                    // Create new settings file.                    m_settings.AppendChild(m_settings.CreateNode(XmlNodeType.XmlDeclaration, null, null));                    m_settings.AppendChild(m_settings.CreateElement(RootNode));                }            }             public string FileName            {                get                {                    return m_fileName;                }            }             public void Save(bool forceSave)            {                if (forceSave || m_settingsModified)                {                    // Create directory if missing.                    string folder = FilePath.GetDirectoryName(m_fileName);                     if (!Directory.Exists(folder))                        Directory.CreateDirectory(folder);                     // Save settings to the file.                    m_settings.Save(m_fileName);                }            }             public void Write(string category, string name, string value)            {                XmlNode node = GetSetting(category, name);                 if ((object)node != null)                {                    // Setting exists so update it.                    node.SetAttributeValue("value", value);                }                else                {                    // Setting doesn't exist so add it.                    XmlNode setting = m_settings.CreateElement("add");                    setting.SetAttributeValue("name", name);                    setting.SetAttributeValue("value", value);                    m_settings.GetXmlNode(category).AppendChild(setting);                }                 m_settingsModified = true;            }             public string Read(string category, string name, string defaultValue)            {                XmlNode node = GetSetting(category, name);                 // If setting exists, return its value                if ((object)node != null && (object)node.Attributes != null)                    return node.Attributes["value"].Value;                 // Setting doesn't exist so return the default                return defaultValue;            }             public XmlNode GetSetting(string category, string name)            {                return m_settings.SelectSingleNode(string.Format("{0}/{1}/add[@name='{2}']", RootNode, category, name));            }        }         // Constants        private const string CustomSectionName = "categorizedSettings";        private const string CustomSectionType = "GSF.Configuration.CategorizedSettingsSection, GSF.Core";         // Fields        private string m_cryptoKey;        private CultureInfo m_culture;        private System.Configuration.Configuration m_configuration;        private UserConfigurationFile m_userConfiguration;        private volatile ConfigurationSaveMode m_saveMode;        private readonly LongSynchronizedOperation m_saveOperation;        internal bool m_forceSave;         #endregion         #region [ Constructors ]         /// <summary>        /// Initializes a new instance of the <see cref="ConfigurationFile"/> class.        /// </summary>                internal ConfigurationFile(string configFilePath)        {            m_culture = CultureInfo.InvariantCulture;             // Do not run the save operation on a background thread since the application may be            // performing the save as a final step during shutdown and the save operation must            // complete, incomplete saves can cause a zero length config file to be created.            m_saveOperation = new LongSynchronizedOperation(ExecuteConfigurationSave)            {                IsBackground = false            };             m_configuration = GetConfiguration(configFilePath);             if (m_configuration.HasFile && File.Exists(m_configuration.FilePath))                ValidateConfigurationFile(m_configuration.FilePath);            else                CreateConfigurationFile(m_configuration.FilePath);             m_configuration = GetConfiguration(configFilePath);            m_userConfiguration = new UserConfigurationFile();        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets the <see cref="CultureInfo"/> to use for the conversion of setting values to and from <see cref="string"/>.        /// </summary>        public CultureInfo Culture        {            get            {                return m_culture;            }            set            {                if ((object)value != null)                    m_culture = value;                else                    m_culture = CultureInfo.InvariantCulture;            }        }         /// <summary>        /// Get the underlying <see cref="System.Configuration.Configuration"/> that can be accessed using this <see cref="ConfigurationFile"/> object.        /// </summary>        public System.Configuration.Configuration Configuration        {            get            {                return m_configuration;            }        }         /// <summary>        /// Gets the <see cref="CategorizedSettingsSection"/> object representing settings under the "categorizedSettings" section of the config file.        /// </summary>        public CategorizedSettingsSection Settings        {            get            {                CategorizedSettingsSection settings = (CategorizedSettingsSection)m_configuration.GetSection(CustomSectionName);                settings.File = this;                settings.SetCryptoKey(m_cryptoKey);                return settings;            }        }         /// <summary>        /// Gets the <see cref="UserConfigurationFile"/> where user specific settings are saved.        /// </summary>        internal UserConfigurationFile UserSettings        {            get            {                return m_userConfiguration;            }        }         private string BackupConfigFilePath        {            get            {                string filePath = m_configuration.FilePath;                return Path.Combine(FilePath.GetDirectoryName(filePath), FilePath.GetFileNameWithoutExtension(filePath) + ".config.backup");            }        }         #endregion         #region [ Methods ]         /// <summary>        /// Writes the configuration settings contained within this <see cref="ConfigurationFile"/> object to the configuration file that it represents.        /// </summary>        public void Save()        {            Save(m_forceSave ? ConfigurationSaveMode.Full : ConfigurationSaveMode.Modified);        }         /// <summary>        /// Writes the configuration settings contained within this <see cref="ConfigurationFile"/> object to the configuration file that it represents.        /// </summary>        /// <param name="saveMode">One of the <see cref="ConfigurationSaveMode"/> values.</param>        public void Save(ConfigurationSaveMode saveMode)        {            m_saveMode = saveMode; #if MONO            // As of Mono v3.8.0, threads are killed even when marked as non-background (at least on Linux)            m_saveOperation.Run();#else            m_saveOperation.RunOnceAsync();#endif        }         private void ExecuteConfigurationSave()        {            ConfigurationSaveMode saveMode = m_saveMode;            m_userConfiguration.Save(saveMode == ConfigurationSaveMode.Full);            m_configuration.Save(saveMode, m_forceSave);            m_forceSave = false;             try            {                // Attempt to create a backup configuration file#if MONO                m_configuration.SaveAs(BackupConfigFilePath, ConfigurationSaveMode.Full);#else                File.Copy(m_configuration.FilePath, BackupConfigFilePath, true);#endif            }            catch            {                // May not have needed rights to save backup configuration file            }        }         /// <summary>        /// Writes the configuration settings contained within this <see cref="ConfigurationFile"/> object to the specified configuration file.        /// </summary>        /// <param name="fileName">The path and file name to save the configuration file to.</param>        public void SaveAs(string fileName)        {            m_configuration.SaveAs(fileName);        }         /// <summary>        /// Reloads the current configuration settings from the configuration file that the <see cref="ConfigurationFile"/> represents.        /// </summary>        public void Reload()        {            m_configuration = GetConfiguration(m_configuration.FilePath);            m_userConfiguration = new UserConfigurationFile();        }         /// <summary>        /// Restores all the default settings for <see cref="SettingScope.User"/> scoped settings.        /// </summary>        public void RestoreDefaultUserSettings()        {            if ((object)m_userConfiguration != null)            {                string fileName = m_userConfiguration.FileName;                 if (File.Exists(fileName))                    File.Delete(fileName);                 m_userConfiguration = new UserConfigurationFile();            }        }         /// <summary>        /// Sets the key to be used for encrypting and decrypting values of <see cref="Settings"/>.        /// </summary>        /// <param name="cryptoKey">New crypto key.</param>        public void SetCryptoKey(string cryptoKey)        {            m_cryptoKey = cryptoKey;        }         private System.Configuration.Configuration GetConfiguration(string configFilePath)        {            ApplicationType appType = Common.GetApplicationType();            System.Configuration.Configuration configuration;             if ((object)configFilePath != null)            {                if (string.IsNullOrEmpty(configFilePath) || string.Compare(FilePath.GetExtension(configFilePath), ".config", StringComparison.OrdinalIgnoreCase) == 0)                {                    // PCP - 12/12/2006: Using the TrimEnd function to get the correct value that needs to be passed                    // to the method call for getting the Configuration object. The previous method (String.TrimEnd())                    // yielded incorrect output resulting in the Configuration object not being initialized correctly.                    switch (appType)                    {                        case ApplicationType.Web:                            if (string.IsNullOrEmpty(configFilePath))                                configFilePath = HostingEnvironment.ApplicationVirtualPath;                            configuration = WebConfigurationManager.OpenWebConfiguration(TrimEnd(configFilePath, "web.config"));                            break;                        default:                            configuration = ConfigurationManager.OpenExeConfiguration(TrimEnd(configFilePath, ".config").EnsureEnd(".exe"));

Lines 1–500 of 651.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t