浅谈config文件的使用

时间:2022-09-03 19:10:50

一、缘起

最近做项目开始使用C#,因为以前一直使用的是C++,因此面向对象思想方面的知识还是比较全面的,反而是因没有经过完整、系统的.Net方面知识的系统学习,经常被一些在C#老鸟眼里几乎是常识的小知识点给绊倒。

为什么这么说呢,因为我在网络上查找的资料的时候,经常大部分问题,都是能够找到或多或少的参考资料,但是这些小知识点却很少能够找到正确的解决方法,有也是只有提问,没有回到,那么这种情况出现,就只有2种解释:
1、这个方面的问题很难,难到没有人能够解决;
2、这个问题太简单,简单到稍微熟悉的人都不屑于回答,提问者也在一番思考后,轻松找到答案。(我比较倾向这个,呵呵,因此我也把这些小知识,叫做:容易被忽略的细节)

然而,无论问题是否简单,既然我会被绊倒,耽搁时间,肯定也会有人被同样耽搁,因此我想把这些细节整理出来,还是具有一定意义的。

于是,本系列文章开始...

二、问题描述

除了正常情况下的config文件,使用ConfigurationManager加载,我们还可能会碰到一下这样的情况:
1、加载非当前应用程序yyy.exe默认的config文件的xxx.exe.config文件;(比如:与yyy.exe.config不在同一目录下 或者 文件名不同)
2、加载非应用程序的xxx.config文件;
3、让类库xxx.dll内的函数读取默认config文件的时候,读取的是xxx.dll同级目录下的xxx.dll.config文件,而不是加载xxx.dll的应用程序yyy.exe的默认应用程序配置文件:yyy.exe.config;
    以上三种情况,都不能直接使用ConfigurationManager来加载

三、解决过程

让我们从最基础、最简单、最常见的config文件的加载来入手,解决上面三个问题:

step1:研究基础的config文件加载

config文件,是给客户端应用程序保存配置信息用的,一般情况,一个应用程序只会有一个这样的文件,在编译之前,叫做App.config,每次使用Visual Studio编译,都会Copy到应用程序的生成目录,且Rename为:应用程序名.config。
    要读取config文件内的信息,只需要使用ConfigurationManager的相关函数和属性即可,因此我们来研究下ConfigurationManager,看看是否能找到解决问题的相关信息。
打开MSDN,找到这样一个方法:

OpenExeConfiguration  已重载。 将指定的客户端配置文件作为 Configuration 对象打开。

OK,要找的就是这个,因为这个方法有一个重载方法是:

OpenExeConfiguration(String)  将指定的客户端配置文件作为 Configuration 对象打开。

step2:加载非当前应用程序默认的config文件

于是,第一个问题的解决方案,似乎、应该、可能找到了,按照MSDN上的说明,若我们把要打开的xxx.exe.config的路径作为参数传入即可,代码如下:

Configuration config = ConfigurationManager.OpenExeConfiguration("C:\\xxx.exe.config");
   DllInfo dllInfo = config.GetSection("DllInfo") as DllInfo;
   Console.WriteLine(dllInfo);

但是,事情并没有这么顺利,这样是无法打开xxx.exe.config文件的,经过调试,发现:config的属性FilePath的值为:"C:\\xxx.exe.config.config",程序自己在传入的参数后增加了“.config”作为要打开的config文件的路径,这显然和我们之前从MSDN上所看到的不一样,不用说,我们被微软小小的耍了一把。这里要传入的参数,不应该是要打开的config的路径,而应该是这个config文件对应的应用程序的路径,也就是说上面的代码应该这样写:

Configuration config = ConfigurationManager.OpenExeConfiguration("C:\\xxx.exe"); // 写的是应用程序的路径
   DllInfo dllInfo = config.GetSection("DllInfo") as DllInfo;
   Console.WriteLine(dllInfo);

再次运行,呵呵,还是不行,提示错误:『加载配置文件时出错: 参数“exePath”无效。参数名: exePath』。显然我们有被耍了,这里要传入应用程序路径(exePath)没错,但是因为我们并没有在xxx.exe.config文件同目录下,加入xxx.exe文件,因此我们传入的exePath实际上是无效的,可见为了能够加载xxx.exe.config,我们弄一个xxx.exe文件放在一起。

ok,运行,成功。

小结1:第一个问题的解决方案找到:

使用ConfigurationManager.OpenExeConfiguration(string exePath)即可,同时注意2个小细节:
A:改方法需传入的是exePath,而不是configPath;
B:exePath必须是有效的,因此xxx.exe和xxx.exe.config应该成对出现,缺一不可。

step3:扩展step2的战果,找到加载xxx.config的方法

step2已经找到了加载xxx.exe.config的方法,观察xxx.exe.config的名称,发现,若把xxx.exe看成YYY,显然xxx.exe.config = YYY.config,也就是说:xxx.exe.config是xxx.config中比较特殊的一种,他要求config文件的文件名最后4个字母必须是“.exe”。

此时,大胆推测,使用ConfigurationManager.OpenExeConfiguration(string exePath),应该可以解决问题。

Configuration config = ConfigurationManager.OpenExeConfiguration("C:\\xxx"); // 记得要有xxx文件,否则这个路径就是无效的了。
   DllInfo dllInfo = config.GetSection("DllInfo") as DllInfo;
   Console.WriteLine(dllInfo);

运行,HOHO,成功了。

小结2:第二个问题和第一个问题的解决方案一样。

step4:扩展xxx.config解决问题3

继续扩大战果,还是从文件名上来找思路,我们要加载的xxx.dll.config,其实也是xxx.config中稍微特殊的一种,显然也可以和step3那样处理。

使用OpenExeConfiguration(string exePath)来解决问题三,在dll内,碰到需要读取config文件信息的时候,放弃使用ConfigurationManager的函数或属性直接获取,而改用OpenExeConfiguration(string exePath)加载config文件为一个Configuration对象的对应函数或属性即可。

小结3:第三个问题同样可以按照第一个问题的方案来做。

四、额外的思考

在应用程序yyy.exe中通过ConfigurationManager可以很方便的读取到yyy.exe.config文件中的信息,但在类库中使用ConfigruationManager读取的却不是自动编译生成的xxx.dll.cofig文件,而是引用类库的应用程序yyy.exe的yyy.exe.config文件。

有没有什么办法,让类库中的ConfigurationManager读取的也是他默认的xxx.dll.config文件呢?

其实,是可以的,不过这里涉及到了应用程序域(AppDomain)的概念, .Net上的应用程序都是运行在一个应用程序域(AppDomain)内的,在程序启动之初,都会默认启动一个AppDomain,查看MSDN可以看到AppDomain有一个属性:SetupInformation,这个属性保存的就是当前域的config文件路径;可惜,这个属性是只读的,所以我们默认AppDomain的config文件路径。

因此,若想让类库能够直接使用ConfigurationManager来读取自己默认的config文件,就只能把类库放在一个新的AppDomain中执行,并且在创建AppDomain的时候指定他的SetupInformation为类库默认的config文件路径;AppDomain有一个用来创建新AppDomain的方法:CreateDomain(String, Evidence, AppDomainSetup);只要把第三个参数的属性ConfigurationFile只想类库默认的config文件路径即可。

浅谈config文件的使用的更多相关文章

  1. 浅谈头文件(.h)和源文件(.cpp)的区别

    浅谈头文件(.h)和源文件(.cpp)的区别 本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮.经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能.分门别类展开的文件构成的.一锅 ...

  2. 浅谈.htaccess文件--避免滥用.htaccess文件

    .htaccess文件提供了一种目录级别的修改配置的方式. NOTE: 如果你拥有修改apache配置文件的权限,那么完全没有必要使用.htaccess文件.使用.htaccess文件会拖慢apach ...

  3. shell实例浅谈之六文件特定行打印的多种方法

    一.问题 Sed和AWK在处理文件方面有很强的优势,还有head和tail等文件处理工具的使用,grep也可实现文本的搜索.上述命令都可以在后面直接加文件名,不需要在前面使用cat添加管道,cat会影 ...

  4. 浅谈Linux文件与目录权限

    作为一个程序员,在工作的过程中或多或少都会接触都Linux,那么对于权限这块肯定有所了解,今天有空想谈谈觉得比较绕的权限问题,即文件权限与目录权限 1.文件权限,对于文件权限这个是比较简单的,也很容易 ...

  5. 浅谈hosts文件

    1.什么是hosts文件?这个文件在哪? hosts文件(域名解析文件)是将主机名映射到IP地址的一个纯文本文件,原始名称是HOSTS.TXT(IP,Internet Protocol,Interne ...

  6. 浅谈CVE-2018-12613文件包含/buuojHCTF2018签到题Writeup

    文件包含 蒻姬我最开始接触这个 是一道buuoj的web签到题 进入靶机,查看源代码 <!DOCTYPE html> <html lang="en"> &l ...

  7. c&num;Winform程序调用app&period;config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门&lpar;一&rpar;----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  8. 浅谈内核的Makefile、Kconfig和&period;config文件

    Linux内核源码文件繁多,搞不清Makefile.Kconfig..config间的关系,不了解内核编译体系,编译修改内核有问题无从下手,自己写的驱动不知道怎么编进内核,不知道怎么配置内核,这些问题 ...

  9. 浅谈qmake之pro、pri、prf、prl文件

    浅谈qmake之pro.pri.prf.prl文件 转载自:http://blog.csdn.net/dbzhang800/article/details/6348432 尽管每次和cmake对比起来 ...

随机推荐

  1. BIEE 配置邮箱服务器

    找个免费邮件服务器126或者163的 登录em地址,点击“部署”——>“邮件”——>“锁定并编辑”——>应用——>激活更改——>重新启动以应用最近更改——>重新启动 ...

  2. 《zw版&&num;183&semi;delphi与halcon系列原创教程》hello&comma;zw

    <zw版·delphi与halcon系列原创教程>hello,zw 按惯例,第一个程序是‘hello’ 毕竟,Halcon是专业的图像库,所以我们就不用纯文本版的,来一个专业版.Halco ...

  3. DOM操作--表格点击行变色

    点击表格行变色,这种网页效果应该还是比较常见的.大家应该看见了,我这里的效果是用DOM操作实现的,那么很多人会问什么是DOM操作,贴出代码之前我就和大家解释一下什么是DOM操作: DOM是Docume ...

  4. D15

    T3: 树上的递归,很裸 T4:题目模型:二分染色问题 以及根据ccy大神指点,理解树形dp可以从 没有上司的舞会 聚会的快乐 这两题入手

  5. 演讲小技巧iPhone&plus;Keynote

    原文发布在简书上:http://www.jianshu.com/p/a45538ca611f 今天在公司里分享了一个技术雷达里关于 ECMAScript 2017 的小 Session,分享加问答总共 ...

  6. SQLite常用函数及语句

    SQLite3.0使用的是C的函数接口,常用函数如下: sqlite3_open() //打开数据库 sqlite3_close() //关闭数据库 sqlite3_exec() //执行sql语句, ...

  7. JavaScript(二)

    获取元素方法一 可以使用内置对象document上的getElementById方法来获取页面上设置了id属性的元素,获取到的是一个html对象,然后将它赋值给一个变量,比如: <script ...

  8. 简单读!spring-mvc源码之url的暴露之路

    spring中,注册controller的url有多种方式: 1. 你可以啥都不都干,直接使用 @RequestMapping 注解上体路径,然后加上 <component-scan>, ...

  9. Vue学习之路4-v-bind指令

    1. 定义 1.1 v-bind 指令被用来响应地更新 HTML 属性,其实它是支持一个单一 JavaScript 表达式 (v-for 除外). 2. 语法 2.1 完整语法:<span v- ...

  10. Jmeter测试http&plus;JSON配置相关

    1.添加HTTP信息头管理器 Content-Type application/json Accept application/json 2.添加http请求(方法.编码.路径.body)