WPF程序中App.Config文件的读与写

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 原文:WPF程序中App.Config文件的读与写   WPF程序中的App.Config文件是我们应用程序中经常使用的一种配置文件,System.Configuration.dll文件中提供了大量的读写的配置,所以它是一种高效的程序配置方式,那么今天我就这个部分来做一次系统性的总结。
原文: WPF程序中App.Config文件的读与写

   WPF程序中的App.Config文件是我们应用程序中经常使用的一种配置文件,System.Configuration.dll文件中提供了大量的读写的配置,所以它是一种高效的程序配置方式,那么今天我就这个部分来做一次系统性的总结。

        App.Config文件是系统默认的应用程序配置文件,在我们使用后进行编译时会生成“程序集名称+.exe.config”文件,其本质上也是一个XML文件,在我们的应用程序中添加应用程序配置文件后,默认生成下面的内容。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>

  后面可以根据需要添加我们想要配置的内容,例如我们想要自定义一个section,那么我们首先需要增加一个configSections节点,然后再添加section子节点,在子节点中我们需要添加名称name 类型type等节点信息,具体配置信息如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>  
 <configSections>
   <section name="eas" type="EAS.ConfigHandler,EAS.MicroKernel"/>
   <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"                           requirePermission="false"/>
  </configSections>
  <eas> 
    <objects>
      <object  name="MessageBus" assembly="EAS.MicroKernel" type="EAS.Sockets.Bus.SocketBus" LifestyleType="Singleton">
        <property name="Url" type="string" value="socket.tcp://127.0.0.1:1000/"/>
      </object>
    </objects>
  </eas>  
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
    <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"></provider>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
    </providers>
  </entityFramework>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
  </startup>
  <appSettings>    
    <add key="AspNetAddress" value="http://192.168.3.199:8088"/>   
    <add key="ServerDog" value="192.168.3.199:8001"/>
    <add key="DICSCtrl" value="192.168.3.100:4503"/> 
    <add key="BGServerDeamon" value="192.168.3.199:5915"/>
    <add key="MySQLServer" value="localhost"/>
    <add key="DataSimulator" value="DataRinse"/>
    <!--当前软件部署的时间-->
    <add key="DeploymentTime" value="20170822"/>
    <add key="UnitWidth" value="1920"/>
    <!--单个屏幕高-->
    <add key="UnitHeight" value="1080"/>
    <!--横向屏幕数量-->
    <add key="HorizontalCount" value="2"/>
    <!--竖向屏幕数量-->
    <add key="VerticalCount" value="2"/>  
  </appSettings> 
</configuration>

  这其中最常用的就是appSettings节点了,通过添加key和value能够快速添加键值对,从而完成参数的配置与读写操作。

       第一部分:基础篇

  这一部分主要介绍最常用的操作,那就是读取操作了。 

 string sqlServer= System.Configuration.ConfigurationSettings.AppSettings["MySQLServer"]; 

通过输入唯一的key就可以来查找当前key对应的value值的内容了。

       后面就是为App.Config文件来写入值了,我们首先来看如何为其中的某一个节点写入值的操作。

  1 将当前应用程序的配置文件作为 System.Configuration.Configuration 对象打开。

System.Configuration.Configuration  config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);

  上面打开特定的exe.config文件的形式和下面的类似,都可以打开exe.config文件的内容,只不过下面这种方式更为灵活。

 ExeConfigurationFileMap map = new ExeConfigurationFileMap();
 Assembly assembly = Assembly.GetCallingAssembly();
 Uri uri = new Uri(Path.GetDirectoryName(assembly.CodeBase));
 map.ExeConfigFilename = Path.Combine(uri.LocalPath, assembly.GetName().Name + ".exe.config");
 System.Configuration.Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(map, 0);
 string sqlServer = configuration.AppSettings.Settings["MySQLServer"].Value;    

  2 读取和写入特定的项

//读取
string sqlServer = config.AppSettings.Settings["MySQLServer"].Value;
//写入
config.AppSettings.Settings["MySQLServer"].Value = "XXX";
//增加节点
 config.AppSettings.Settings.Add("MySQLServer","XXX");

  3 写入后要进行保存,并刷新

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

  这样我们就完成了整个读取和写入的操作了,基础的操作部分也就包含这么多的部分,通过这些操作能够对常规的一些操作进行处理,并完成软件的一些基础的要求。

  第二部分:提高篇

  这个部分我们来将一些稍微复杂一点的操作,对于appsettings中的操作,我们当然可以非常轻松的通过这些操作来完成配置,但是如果是自定义的section节点中的特定值那么我们应该怎样来进行读写操作呢?我们想其实app.config文件本质上也是一个xml文件,其实我们完全可以按照常规的xml操作的方式来进行读写操作,下面的代码以读取自定义节点中的xml文件为例来进行说明。 

  private void DoSaveConfig()
        {
            try
            {
                var section = config.GetSection("eas");
                var sontSection = section.CurrentConfiguration.GetSection("objects");
                string filePath = section.CurrentConfiguration.FilePath;
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(filePath);
                #region 保存EAS部分
                XmlNode easNode = ((System.Xml.XmlElement)(xmlDoc.SelectSingleNode("configuration/eas/objects/object/property")));
                string currentValue = easNode.Attributes["value"].Value;
                string[] infos = currentValue.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                if (infos.Length == 2)
                {
                    string info = infos[1];
                    string[] ipport = info.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
                    string oldIp = ipport[0];
                    string oldPort = ipport[1];
                    StringBuilder sb = new StringBuilder();
                    sb.Append("socket.tcp://").Append(ServerIp).Append(":").Append(oldPort).Append("/");
                    easNode.Attributes["value"].Value = sb.ToString();
                }
                #endregion

                XmlNode appSettingsNode = xmlDoc.SelectSingleNode("configuration/appSettings");
                foreach (XmlNode childNode in appSettingsNode.ChildNodes)
                {
                    if (childNode.NodeType == XmlNodeType.Element)
                    {
                        switch (childNode.Attributes["key"].Value)
                        {
                            case "AspNetAddress":
                                StringBuilder web = new StringBuilder();
                                childNode.Attributes["value"].Value = web.Append("http://").Append(ServerIp).Append(":").Append(WebPort).ToString();
                                break;
                            case "ServerDog":
                                StringBuilder serverDog = new StringBuilder();
                                childNode.Attributes["value"].Value = serverDog.Append(ServerIp).Append(":").Append(ServerDogPort).ToString();
                                break;
                            case "DICSCtrl":
                                StringBuilder processor = new StringBuilder();
                                childNode.Attributes["value"].Value = processor.Append(ProcessorIp).Append(":").Append(ProcessorPort).ToString();
                                break;
                            case "BGServerDeamon":
                                StringBuilder bgserverdeamon = new StringBuilder();
                                childNode.Attributes["value"].Value = bgserverdeamon.Append(ServerIp).Append(":").Append(BGServerDeamonPort).ToString();
                                break;
                            case "MySQLServer":
                                childNode.Attributes["value"].Value = ServerIp;
                                break;
                            case "DeploymentTime":
                                DeployTime = DateTime.Now.ToString("yyyy-MM-dd");
                                childNode.Attributes["value"].Value = DeployTime;
                                break;
                            case "UnitWidth":
                                childNode.Attributes["value"].Value = UnitWidth.ToString();
                                break;
                            case "UnitHeight":
                                childNode.Attributes["value"].Value = UnitHeight.ToString();
                                break;
                            case "HorizontalCount":
                                childNode.Attributes["value"].Value = HCount.ToString();
                                break;
                            case "VerticalCount":
                                childNode.Attributes["value"].Value = VCount.ToString();
                                break;
                            case "CurrentVersion":
                                childNode.Attributes["value"].Value = CurrentVersion;
                                break;
                            case "PartialGISAddress":
                                childNode.Attributes["value"].Value = GISPath;
                                break;
                            case "MediaShareFolder":
                                childNode.Attributes["value"].Value = DiskMapPath;
                                break;
                            case "MediaSharedRemoteFolder":
                                StringBuilder mediasharedfolder = new StringBuilder();
                                childNode.Attributes["value"].Value = mediasharedfolder.Append(@"\\").Append(ServerIp).Append(@"\SharedResources").ToString();
                                break;
                            case "DynamicHTMLsPath":
                                childNode.Attributes["value"].Value = HTMLPath;
                                break;
                            default:
                                break;
                        }
                    }
                }
                xmlDoc.Save(filePath);
                MessageBox.Show("配置文件参数保存成功,重启软件后生效!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ;
            }
        } 

  这其中 config为第一部分中打开的System.Configuration.Configuration 对象,后面的部分就是一些常规的XML文件的一些操作,首先是Load然后再配置节点信息,这里配置节点的时候需要注意的是当前XmlNodeType,这个是必须要进行确认的,只有当前的XMLNodeType为Element的项才能够进行key和value的值的读写,其它的都是一些常规的操作,具体内容请参考下面的DEMO中的部分代码。

  在上面的代码中,加载xml文件到XmlDocument中除了采用xmlDoc.Load("具体路径")的方式之外,还可以采用下面的方式来进行,这里我们需要去比较两种方式的优劣。

 string xml = ((System.Xml.XmlElement)(System.Configuration.ConfigurationManager.GetSection("eas"))).InnerXml;
 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(xml);  

  第三部分:扩展篇

  为什么要自定义的配置节点?
  确实,有很多人在使用config文件都是直接使用appSetting的,把所有的配置参数全都塞到那里,这样做虽然不错, 但是如果参数过多,这种做法的缺点也会明显地暴露出来:appSetting中的配置参数项只能按key名来访问,不能支持复杂的层次节点也不支持强类型, 而且由于全都只使用这一个集合,你会发现:完全不相干的参数也要放在一起!

  想摆脱这种困扰吗?自定义的配置节点将是解决这个问题的一种可行方法。

  关于这方面的具体描述,请参考这里,并从当前位置下载DEMO查看具体的实例。

  最后将整个部分的测试用的DEMO放在这里,如果需要的话请点击此处进行下载。

 

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
30天前
|
移动开发 开发框架 小程序
uni-app:demo&媒体文件&配置全局的变量(三)
uni-app 是一个使用 Vue.js 构建多平台应用的框架,支持微信小程序、支付宝小程序、H5 和 App 等平台。本文档介绍了 uni-app 的基本用法,包括登录示例、媒体文件处理、全局变量配置和 Vuex 状态管理的实现。通过这些示例,开发者可以快速上手并高效开发多平台应用。
|
30天前
|
Linux 开发工具 数据安全/隐私保护
linux异常一:feng 不在 sudoers 文件中,此事将被报告。yum提示Another app is currently holding the yum lock; waiting for
这篇文章介绍了在CentOS 7系统中安装Docker时遇到的两个常见问题及其解决方法:用户不在sudoers文件中导致权限不足,以及yum被锁定的问题。
37 2
linux异常一:feng 不在 sudoers 文件中,此事将被报告。yum提示Another app is currently holding the yum lock; waiting for
|
24天前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
119 0
|
3月前
|
JSON Linux 网络安全
【Azure 应用服务】如何从App Service for Linux 的环境中下载Container中非Home目录下的文件呢?
【Azure 应用服务】如何从App Service for Linux 的环境中下载Container中非Home目录下的文件呢?
|
3月前
|
API 网络架构
【Azure Logic App】在中国区的微软云服务上,使用逻辑应用是否可以下载SharePoint上的文件呢?
【Azure Logic App】在中国区的微软云服务上,使用逻辑应用是否可以下载SharePoint上的文件呢?
【Azure Logic App】在中国区的微软云服务上,使用逻辑应用是否可以下载SharePoint上的文件呢?
|
3月前
|
C# 开发者 Windows
WPF与PDF文档:解锁创建和编辑PDF文件的新技能——从环境配置到代码实践,手把手教你如何在WPF应用中高效处理PDF,提升文档管理效率
【8月更文挑战第31天】随着数字文档的普及,PDF因跨平台兼容性和高保真度成为重要格式。WPF虽不直接支持PDF处理,但借助第三方库(如iTextSharp)可在WPF应用中实现PDF的创建与编辑。本文通过具体案例和示例代码,详细介绍了如何在WPF中集成PDF库,并展示了从设计用户界面到实现PDF创建与编辑的完整流程。不仅包括创建新文档的基本步骤,还涉及在现有PDF中添加页眉页脚等高级功能。通过这些示例,WPF开发者可以更好地掌握PDF处理技术,提升应用程序的功能性和实用性。
125 0
|
3月前
|
C# 开发者 UED
WPF开发者必备秘籍:深度解析文件对话框使用技巧,打开与保存文件原来如此简单!
【8月更文挑战第31天】在WPF应用开发中,文件操作是常见需求。本文详细介绍了如何利用`Microsoft.Win32`命名空间下的`OpenFileDialog`和`SaveFileDialog`类来正确实现文件打开与保存功能。通过示例代码展示了如何设置文件过滤器、初始目录等属性,并使用对话框进行文件读写操作。正确使用文件对话框能显著提升用户体验,使应用更友好易用。
71 0
|
3月前
|
前端开发 JavaScript Linux
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败
|
3月前
|
Java Linux 网络安全
【Azure 应用服务】App Service for Linux环境中,如何解决字体文件缺失的情况
【Azure 应用服务】App Service for Linux环境中,如何解决字体文件缺失的情况
|
3月前
|
Java Linux C++
【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
【Azure 应用服务】App Service For Linux 部署Java Spring Boot应用后,查看日志文件时的疑惑
下一篇
无影云桌面