zoukankan      html  css  js  c++  java
  • [转载]C# 动态修改配置文件

     

     

    在做一些数据库应用程序的时候经常遇到动态配置数据库,所以写了一个小程序,利用App.Config动态读写数据库连接字符串,那些还在用Adapter控件的同志们赶紧抛弃吧。

    主要实现代码:

    代码
    using System.Configuration;
    using System.Data.OleDb;

    //
    string strconn = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;

    //
    private void saveConnection(string connstring)
            {
                
    //保存连接
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.ConnectionStrings.ConnectionStrings.Remove("ConnString");
                ConnectionStringSettings mySettings = new ConnectionStringSettings("ConnString", connstring, "SQLOLEDB");
                config.ConnectionStrings.ConnectionStrings.Add(mySettings);
                config.Save(ConfigurationSaveMode.Modified);
                
    // 强制重新载入配置文件的ConnectionStrings配置节
                ConfigurationManager.RefreshSection("ConnectionStrings");
            }

    //----------------------------------------------------

     

    public class ConfigureAppConfig
        {
            //静态构造,不能实例化
            static ConfigureAppConfig() { }

            /**//// <summary>
            /// 获取AppSettings配置节中的Key值
            /// </summary>
            /// <param name="keyName">Key's name</param>
            /// <returns>Key's value</returns>
            public static string GetAppSettingsKeyValue(string keyName)
            {
                return ConfigurationManager.AppSettings.Get(keyName);
            }

            /**//// <summary>
            /// 获取ConnectionStrings配置节中的值
            /// </summary>
            /// <returns></returns>
            public static string GetConnectionStringsElementValue()
            {
                ConnectionStringSettings settings = System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"];
                return settings.ConnectionString;
            }

            /**//// <summary>
            /// 保存节点中ConnectionStrings的子节点配置项的值
            /// </summary>
            /// <param name="elementValue"></param>
            public static void ConnectionStringsSave(string ConnectionStringsName, string elementValue)
            {
                System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.ConnectionStrings.ConnectionStrings["connectionString"].ConnectionString = elementValue;
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("connectionStrings");
            }

            /**//// <summary>
            /// 判断appSettings中是否有此项
            /// </summary>
            private static bool AppSettingsKeyExists(string strKey, Configuration config)
            {
                foreach (string str in config.AppSettings.Settings.AllKeys)
                {
                    if (str == strKey)
                    {
                        return true;
                    }
                }
                return false;
            }

            /**//// <summary>
            /// 保存appSettings中某key的value值
            /// </summary>
            /// <param name="strKey">key's name</param>
            /// <param name="newValue">value</param>
            public static void AppSettingsSave(string strKey, string newValue)
            {
                System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                if (AppSettingsKeyExists(strKey, config))
                {
                    config.AppSettings.Settings[strKey].Value = newValue;
                    config.Save(ConfigurationSaveMode.Modified);
                    ConfigurationManager.RefreshSection("appSettings");
                }
            }
        }
    如果你的程序是对其它程序的配置文件进行操作,代码如下:
                ExeConfigurationFileMap filemap = new ExeConfigurationFileMap();
                filemap.ExeConfigFilename = filePath;//配置文件路径
                config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);

                if (AppSettingsKeyExists("Refresh", config))
                {
                    config.AppSettings.Settings["Refresh"].Value = M_TimeRead.ToString();
                }

                if (AppSettingsKeyExists("MachineNo", config))
                {
                    config.AppSettings.Settings["MachineNo"].Value = M_MachineNo;

                }
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");

                config.ConnectionStrings.ConnectionStrings["connectionString"].ConnectionString = M_ConnectionString;
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("connectionStrings");
    数据库字符串加密
    ExeConfigurationFileMap filemap = new ExeConfigurationFileMap();
                filemap.ExeConfigFilename = Application.ExecutablePath + ".Config"; //filePath;
                config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
                //指定我所要的节点
                ConfigurationSection section = config.ConnectionStrings;

                if ((section.SectionInformation.IsProtected == false) && (section.ElementInformation.IsLocked == false))
                {
                    //制定节点加密
                    section.SectionInformation.ProtectSection(protect);
                    //即使没有修改也保存设置
                    section.SectionInformation.ForceSave = true;
                    //配置文件内容保存到xml
                    config.Save(ConfigurationSaveMode.Full);
                }

    //----------------------------------------------------

     

     

    扩展Configuration的功能

    获取连接字符串

    View Code
            ///<summary>依据连接串名字connectionName返回数据连接字符串 </summary>
            ///<param name="connectionName">连接串的</param>
            ///<param name="config"></param>
            ///<returns></returns>
            public static string GetConnectionStringsConfig(this Configuration config, string connectionName)
            {
                string connectionString = config.ConnectionStrings.ConnectionStrings[connectionName].ConnectionString;
                ////Console.WriteLine(connectionString);
                return connectionString;
            }
    复制代码
     

    更新连接字符串

    View Code
            ///<summary>
            ///更新连接字符串 
            ///</summary>
            ///<param name="newName">连接字符串名称</param>
            ///<param name="newConString">连接字符串内容</param>
            ///<param name="newProviderName">数据提供程序名称</param>
            ///<param name="config">Configuration实例</param>
            public static void UpdateConnectionStringsConfig(this Configuration config, string newName, string newConString, string newProviderName)
            {
                bool isModified = false;
                //记录该连接串是否已经存在     
                //如果要更改的连接串已经存在     
                if (config.ConnectionStrings.ConnectionStrings[newName] != null)
                { isModified = true; }

                //新建一个连接字符串实例     
                ConnectionStringSettings mySettings = new ConnectionStringSettings(newName, newConString, newProviderName);

                // 如果连接串已存在,首先删除它     
                if (isModified)
                {
                    config.ConnectionStrings.ConnectionStrings.Remove(newName);
                }
                // 将新的连接串添加到配置文件中.     
                config.ConnectionStrings.ConnectionStrings.Add(mySettings);
                // 保存对配置文件所作的更改     
                config.Save(ConfigurationSaveMode.Modified);
            }
    复制代码
     

    获取appSettings配置节的value项

    View Code
            ///<summary>
            ///返回config文件中appSettings配置节的value项 
            ///</summary>
            ///<param name="strKey"></param>
            ///<param name="config">Configuration实例</param>
            ///<returns></returns>
            public static string GetAppSettingsItemValue(this Configuration config, string strKey)
            {
                foreach (KeyValueConfigurationElement key in config.AppSettings.Settings)
                {
                    if (key.Key == strKey)
                    {
                        return config.AppSettings.Settings[strKey].Value;
                    }
                }
                return string.Empty;
            }
    复制代码
     

    获取所有的appSettings的节点

    View Code
            /// <summary>
            /// 获取所有的appSettings的节点。
            /// </summary>
            /// <param name="config"></param>
            /// <returns></returns>
            public static Dictionary<string,string> GetAppSettings(this Configuration config)
            {
                Dictionary<string,string> dict = new Dictionary<string,string>();
                foreach (KeyValueConfigurationElement key in config.AppSettings.Settings)
                {
                    dict[key.Key] = key.Value;
                }
                return dict;
            }
    复制代码
     

    更新或增加appSettings配置节增加一对键、值对。

    View Code
            ///<summary> 
            ///更新在config文件中appSettings配置节增加一对键、值对。
            ///</summary> 
            ///<param name="newKey"></param> 
            ///<param name="newValue"></param> 
            ///<param name="config"></param>
            public static void UpdateAppSettingsItemValue(this Configuration config, string newKey, string newValue)
            {
                UpdateAppSettingsItemNoSave(config, newKey, newValue);
                ////// Save the changes in App.config file.     
                config.Save(ConfigurationSaveMode.Modified);

                ////// Force a reload of a changed section.     
                ////ConfigurationManager.RefreshSection("appSettings");
            }
    复制代码
     

    删除 appSettings的一个或多个节点
            /// <summary>
            /// 删除 appSettings的一个节点。
            /// </summary>
            /// <param name="config"></param>
            /// <param name="key"></param>
            public static void RemoveAppSettingsItemValue(this Configuration config, string key)
            {
                config.AppSettings.Settings.Remove(key);
                config.Save(ConfigurationSaveMode.Modified);
            }

            /// <summary>
            /// 删除 appSettings的多个节点
            /// </summary>
            /// <param name="config"></param>
            /// <param name="keys"></param>
            public static void RemoveAppSettingsItems(this Configuration config, string[] keys)
            {
                foreach(string key in keys)
                    config.AppSettings.Settings.Remove(key);
                config.Save(ConfigurationSaveMode.Modified);
            }
    复制代码
     

    增加或appSettings配置节增加多对键、值对
            /// <summary>
            ///更新在config文件中appSettings配置节增加多对键、值对。
            /// </summary>
            /// <param name="config"></param>
            /// <param name="items"></param>
            public static void UpdateAppSettings(this Configuration config, Dictionary<string, string> items)
            {
                foreach (string key in items.Keys)
                {
                    UpdateAppSettingsItemNoSave(config, key, items[key]);
                }
                config.Save(ConfigurationSaveMode.Modified);
            }

            private static void UpdateAppSettingsItemNoSave(Configuration config, string newKey, string newValue)
            {
                bool isModified = false;
                foreach (KeyValueConfigurationElement key in config.AppSettings.Settings)
                {
                    if (key.Key == newKey)
                    { isModified = true; }
                }

                // You need to remove the old settings object before you can replace it     
                if (isModified)
                { config.AppSettings.Settings.Remove(newKey); }

                // Add an Application Setting.     
                config.AppSettings.Settings.Add(newKey, newValue);
            }
    复制代码
     

    以上是对connectionStrings 和 appSetting配置节的一些操作,较多的参考网上资源。

    对于DictionarySectionHandler 、NameValueFileSectionHandler 、SingleTagSectionHandler的实现真的不是很多操作,但还是实现了DictionarySectionHandler 、NameValueFileSectionHandler ,至于SingleTagSectionHandler有待进一步实现,或有哪位仁兄实现了,可以回复,谢谢!

    通用获取key-value 键值对Section值的集合
            /// <summary>
            /// 通用获取key-value 键值对Section值的集合,可用于DictionarySectionHandler或NameValueSectionHandler 定义的配置节 NameValueSectionHandler的Key值不能重复
            /// </summary>
            /// <param name="sectionName"></param>
            /// <param name="config"></param>
            /// <returns>没有配置节时返回null</returns>
            public static Dictionary<string, string> GetKeyValueSectionValues(this Configuration config, string sectionName)
            {
                ////KeyValueConfigurationSection appSettings = (KeyValueConfigurationSection)config.GetSection(sectionName);
                var section = config.GetSection(sectionName);

                if (section == null)
                    return null;

                Dictionary<string, string> result = new Dictionary<string, string>();

                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(section.SectionInformation.GetRawXml());
                System.Xml.XmlNode xnode = xdoc.ChildNodes[0];

                IDictionary dict = (IDictionary)(new DictionarySectionHandler().Create(null, null, xnode));
                foreach (string str in dict.Keys)
                {
                    result[str] = (string)dict[str];
                }

                return result;
            }
    复制代码
     

    由于Framework框架没有提供DictionarySection的节点类,不能直接解释出节点中的元素,因些只能使用XML,通过IConfigurationSectionHandler.Create接口,即DictionarySectionHandler().Create方法,实现了元素的集合。

    获取子节点为key-value 键值对的值
            /// <summary>
            /// 获取子节点为key-value 键值对的值,可用于DictionarySectionHandler或NameValueSectionHandler 定义的配置节
            ///
            /// </summary>
            /// <param name="sectionName">定点名称</param>
            /// <param name="key">key 的值,不存在的Key值将返回空</param>
            /// <param name="config">打开的配置文件。</param>
            /// <returns></returns>
            public static string GetKeyValueSectionItemValue(this Configuration config, string sectionName, string key)
            {
                var section = config.GetSection(sectionName).SectionInformation;
                if (section == null)
                    return null;

                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(section.GetRawXml());
                System.Xml.XmlNode xnode = xdoc.ChildNodes[0];

                IDictionary dict = (IDictionary)(new DictionarySectionHandler().Create(null, null, xnode));
                if (dict.Contains(key))
                    return (string)dict[key];
                else
                    return null;
            }
    复制代码
     

    更新配置节,相同的就修改,没有的就增加。
            /// <summary>
            /// 更新配置节,相同的就修改,没有的就增加。
            /// </summary>
            /// <param name="config"></param>
            /// <param name="sectionName"></param>
            /// <param name="items"></param>
            public static void UpdateKeyValueSectionValues(this Configuration config, string sectionName, Dictionary<string, string> items)
            {
                Dictionary<string, string> orgItem = GetKeyValueSectionValues(config, sectionName);
                if (orgItem == null)
                    orgItem = new Dictionary<string, string>();
                foreach (string key in items.Keys)
                {
                    orgItem[key] = items[key];
                }
                UpdateKeyValueSection(config, sectionName, orgItem);
            }

            private static void UpdateKeyValueSection(Configuration config, string sectionName, Dictionary<string, string> items)
            {
                config.Sections.Remove(sectionName);

                AppSettingsSection section = new AppSettingsSection();
                config.Sections.Add(sectionName, section);

                foreach (string key in items.Keys)
                {
                    section.Settings.Add(new KeyValueConfigurationElement(key, items[key]));
                }
                section.SectionInformation.Type = typeof(DictionarySectionHandler).AssemblyQualifiedName;
                config.Save(ConfigurationSaveMode.Modified);
            }
    复制代码
     

    更新配置节在这里使用欺骗的做法,我们使用一个AppSettingsSection 配置节类,把Dictionary的键值对作为KeyValueConfigurationElement元素加入到AppSettingsSection 的Settings集合里,在序列化到Config文件前,把section.SectionInformation.Type 更改为typeof(DictionarySectionHandler).AssemblyQualifiedName的字符串,保存后,我们就可以得到一个DictionarySectionHandler的配置节了,些方法很好地解决了序列化的问题。

    删除配置点的一些配置。
            /// <summary>
            /// 删除配置点的一些配置。
            /// </summary>
            /// <param name="config"></param>
            /// <param name="sectionName"></param>
            /// <param name="items"></param>
            public static void RemoveKeyValueSectionValues(this Configuration config, string sectionName, Dictionary<string, string> items)
            {
                Dictionary<string, string> orgItem = GetKeyValueSectionValues(config, sectionName);
                if (orgItem != null)
                {
                    foreach (string key in items.Keys)
                    {
                        orgItem.Remove(key);
                    }
                    UpdateKeyValueSection(config, sectionName, orgItem);
                }
            }
    复制代码
     

            /// <summary>
            /// 删除配置节。
            /// </summary>
            /// <param name="config"></param>
            /// <param name="sectionName"></param>
            public static void RemoveSection(this Configuration config, string sectionName)
            {
                config.Sections.Remove(sectionName);
                config.Save(ConfigurationSaveMode.Modified);
            }
    复制代码
     

    以上的方法全部完成了配置节的增删改,对于配置节组,由于较少使用,暂时不想去完善了,而且一个组其实可以看作是多个单独配置节的组合,意义不大。

  • 相关阅读:
    Android直方图递增View
    分析实现Android自定义View之扇形图
    可折叠的ToolBar+抽屉菜单NavigationView+浮动按钮FloatButton
    走着官方的教程入门Material Design(一)
    AndroidStudio — Error:Failed to resolve: junit:junit:4.12错误解决
    Win10提示没有权限使用网络资源问题解决
    Android Socket连接PC出错问题及解决
    Android Studio —— 创建Menu菜单项
    Eclipse出现"Running Android Lint has encountered a problem"解决方案
    关于leal和mov
  • 原文地址:https://www.cnblogs.com/fx2008/p/2287793.html
Copyright © 2011-2022 走看看