經(jīng)上一篇文章https://www.cnblogs.com/luna-hehe/p/9104701.html發(fā)現(xiàn)自己對配置文件很是不了解,同樣還是查了半天終于發(fā)現(xiàn)另一片寶貴文檔https://www.cnblogs.com/ysz12300/p/5509576.html 和 https://blog.csdn.net/z702143700/article/details/45913797 和 http://www.cnblogs.com/jhxk/articles/1609182.html(可能是自己用錯(cuò)關(guān)鍵字查詢);
在此只作為自己學(xué)習(xí)記錄的筆記
配置文件一般分為內(nèi)置配置文和用戶自定義配置文件。
內(nèi)置配置文件包括app.config、web.config、Settings.settings( 這個(gè)用的不多,操作也很簡單,在此不詳細(xì)敘述)等等。
用戶自定義配置文件一般是將配置信息放到XML文件或注冊表中,配置信息一般包括程序設(shè)置,記錄運(yùn)行信息,保存控件的信息(比如位置,樣式)。
一、內(nèi)置配置文件操作
app.config和web.config操作類似,以app.config為例,Settings.settings能夠指定值的類型和范圍
1.a(chǎn)pp.config文件操作
該配置文件中主要的節(jié)點(diǎn)有:connectionStrings、appSettings、configSections等,這幾個(gè)屬于常用,操作都略有不同,DotNet提供直接操作各個(gè)節(jié)點(diǎn)的方法。在用到ConfigurationManager時(shí)要添加system.configuration.dll程序集的引用。
程序移植后配置文件的修改會(huì)保存在.exe.config的文件中,但是根據(jù)我經(jīng)驗(yàn)如果你不修改配置文件,一般exe不自動(dòng)創(chuàng)建一個(gè).exe.config的文件。
在項(xiàng)目進(jìn)行編譯后,在bin\Debuge文件下,將出現(xiàn)兩個(gè)配置文件,一個(gè)名為“*.EXE.config”,另一個(gè)名為“*.vshost.exe.config”。第一個(gè)文件為項(xiàng)目實(shí)際使用的配置文件,在程序運(yùn)行中所做的更改都將被保存于此;第二個(gè)文件為原代碼“app.config”的同步文件,在程序運(yùn)行中不會(huì)發(fā)生更改。
1)默認(rèn)App.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <startup> 4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 5 </startup> 6 </configuration>
說明:無論我是建Windows窗體應(yīng)用程序,還是控制臺(tái)應(yīng)用程序,還是Windows服務(wù)默認(rèn)生成的App.config文件都是長這樣的。
< connectionStrings > < add name = "conJxcBook " connectionString = "Data Source=localhost;Initial Catalog=jxcbook;User ID=sa;password=******** " providerName = "System.Data.SqlClient " /> </ connectionStrings >
下面為我自己的項(xiàng)目中的代碼(我本地SQL版本為2012,服務(wù)器SQL版本為2008R2,與上面所述不太一樣):
<connectionStrings> <add name="ConnectionStringMain" connectionString="Data Source=192.168.1.211;Initial Catalog=WLZhuJianMes;Persist Security Info=True;User ID=sa;Password=sa;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /> </connectionStrings>
ConfigurationManager.ConnectionStrings["ConnectionStringMain"].ConnectionString;
往App.config中寫入鏈接字符串
//設(shè)置連接字符串 ConnectionStringSettings setConnStr = newConnectionStringSettings("AccessDB", connectionString,"System.Data.OleDb"); //打開當(dāng)前應(yīng)用程序的app.config文件,進(jìn)行操作 Configuration appConfig =ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); //由于沒有更新連接字符串的方法,所以這里直接再添加一個(gè)連接字符串 appConfig.ConnectionStrings.ConnectionStrings.Add(setConnStr); appConfig.Save(); // 強(qiáng)制重新載入配置文件的ConnectionStrings配置節(jié) ConfigurationManager.RefreshSection("connectionStrings");
< appSettings > < add key = "userName "value = "" /> < add key = "password "value = "" /> < add key = "Department "value = "" /> < add key = "returnValue "value = "" /> < add key = "pwdPattern "value = "" /> < add key = "userPattern "value = "" /> </ appSettings >
在預(yù)定義的 appSettings 節(jié)(注意大小寫),有很多的元素,這些元素名稱都是“add”,有兩個(gè)屬性分別是“key”和“value”。
.NET 提供了對appSettings節(jié)的訪問方法。在 .NET 1.0 和 1.1 版本中,可以使用 System.Configuration.ConfigurationSettings.AppSettings["Key"] 來對 key = "Key" 的<add>元素的 value屬性 進(jìn)行訪問。
注意:現(xiàn)在.Net FrameWork 2.0中已經(jīng)明確表示此ConfigurationSettings屬性已經(jīng)廢棄,建議改為 ConfigurationManager 或 WebConfigurationManager。
使用 System.Configuration.ConfigurationManager,需要在工程里添加對 system.configuration.dll 程序集的引用。(在解決方案管理器中右鍵點(diǎn)擊工程名稱,在右鍵菜單中選擇添加引用,在.NET選項(xiàng)卡下即可找到。)
添加引用后,就可以用 ConfigurationManager.AppSettings["Key"] 來讀取對應(yīng)的值了.
但是,ConfigurationManager.AppSettings 屬性是只讀的,并不支持修改屬性值。這是因?yàn)閾?jù)說微軟不太建議我們動(dòng)態(tài)寫入app.config文件,而是建議手工配置后,在程序運(yùn)行時(shí)只做靜態(tài)訪問。
如果實(shí)在需要在程序中進(jìn)行修改,也即寫入App.Config,請往下看。
讀:
String str = ConfigurationManager.AppSettings["userName"];
讀取App.config文件的appSettings節(jié)的方法比較簡單,可以通過上文中 System.Configuration.ConfigurationManager.AppSettings["Key"]的方法進(jìn)行訪問,但前面也已經(jīng)說了,該方法不提供寫入。
如果希望寫入配置文件,可以使用ConfigurationManager對象執(zhí)行打開配置文件的操作后,將會(huì)返回一個(gè)Configuration的對象,利用該對象進(jìn)行操作(增刪改查都可以哦)。
下面給出實(shí)現(xiàn)的代碼(增加引用using System.Configuration名稱空間)
寫:
private void AccessAppSettings() { //獲取Configuration對象 Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); //根據(jù)Key讀取<add>元素的Value string name = config.AppSettings.Settings["name"].Value; //寫入<add>元素的Value config.AppSettings.Settings["name"].Value = "fx163"; //增加<add>元素 config.AppSettings.Settings.Add("url", "http://www.fx163.net"); //刪除<add>元素 config.AppSettings.Settings.Remove("name"); //一定要記得保存,寫不帶參數(shù)的config.Save()也可以 config.Save(ConfigurationSaveMode.Modified); //刷新,否則程序讀取的還是之前的值(可能已裝入內(nèi)存) System.Configuration.ConfigurationManager.RefreshSection("appSettings"); }
需要注意的是:
1、根據(jù)并不存在的Key值訪問<add>元素,甚至使用remove()方法刪除不存在的元素,都不會(huì)導(dǎo)致異常,前者會(huì)返回null。
2、add已經(jīng)存在的<add>元素也不會(huì)導(dǎo)致異常,而是concat了已有的Value和新的Value,用","分隔,例如:"olldvalue,newvalue"。
3、特別注意大小寫(XML文件是區(qū)分大小寫的),例如appSettings配置節(jié)。
4、可能有讀者會(huì)想到,既然app.config是標(biāo)準(zhǔn)XML,當(dāng)然也可以用操縱一般XML文件的方法來讀寫。這當(dāng)然是可以的!只不過我認(rèn)為這樣就失去了VS提供app.config文件的意義了,還不如自己定義一個(gè)配置文件方便。
4).configSections自定義配置節(jié):自定義configSections,可以自行定義節(jié)元素,擴(kuò)展了appSettings一個(gè)節(jié)的功能
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="quartz" type="System.Configuration.NameValueSectionHandler"/> <section name="sampleSection1" type="System.Configuration.SingleTagSectionHandler"/> <section name="sampleSection2" type="System.Configuration.DictionarySectionHandler"/> </configSections> <quartz> <add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzScheduler"/> <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"/> <add key="quartz.threadPool.threadCount" value="10"/> <add key="quartz.threadPool.threadPriority" value="2"/> <add key="quartz.jobStore.misfireThreshold" value="60000"/> <add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz"/> <!--******************************Plugin配置*********************************************--> <add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" /> <add key="quartz.plugin.xml.fileNames" value="~/quartz_jobs.xml"/> </quartz> <sampleSection1 setting1="Value1" setting2="value two" setting3="third value" /> <sampleSection2> <add key="add" value="id=1"/> <add key="edit" value="id=2"/> </sampleSection2>
name屬性:指的是自定義配置節(jié)的名稱,即自定義的這個(gè)section的名字,
type屬性:指的是自定義配置節(jié)的類型,即用于接收這個(gè)section中相應(yīng)字段的類,主要包括:System.Configuration.SingleTagSectionHandler;System.Configuration.DictionarySectionHandler;System.Configuration.NameValueSectionHandler;不同的type不但設(shè)置配置節(jié)的方式不一樣,最后訪問配置文件的操作上也有差異
在程序中如何訪問這些自定義的配置節(jié),我們用ConfigurationSettings類的靜態(tài)方法GetConfig來獲取自定義配置節(jié)的信息
//訪問配置節(jié)sampleSection1 IDictionary IDTest1 =(IDictionary)ConfigurationSettings.GetConfig("sampleSection1"); string str = (string)IDTest1["setting1"]+" "+(string)IDTest1["setting2"]; MessageBox.Show(str);//輸出 //訪問配置節(jié)sampleSection1的另一個(gè)方法
string[] values1=new string[IDTest1.Count];
IDTest1.Values.CopyTo(values1,0); MessageBox.Show(values1[0]+""+values1[1]); //輸出 //訪問配置節(jié)sampleSection2 IDictionary IDTest2 =(IDictionary)ConfigurationSettings.GetConfig("sampleSection2"); string[] keys=new string[IDTest2.Keys.Count]; string[] values=new string[IDTest2.Values.Count]; IDTest2.Keys.CopyTo(keys,0); IDTest2.Values.CopyTo(values,0); MessageBox.Show(keys[0]+" "+values[0]); //輸出 //訪問配置節(jié)quartz NameValueCollectionnc=(NameValueCollection)ConfigurationSettings.GetConfig("quartz"); MessageBox.Show(nc.AllKeys[0].ToString()+""+nc["Hello"]); //輸出HelloWorld
配置節(jié)處理程序 | 返回類型 |
SingleTagSectionHandler | Systems.Collections.IDictionary |
DictionarySectionHandler | Systems.Collections.IDictionary |
NameValueSectionHandler | Systems.Collections.Specialized.NameValueCollection |
5)sectionGroup:自定義配置節(jié)組
配置節(jié)組是使用<sectionGroup>元素,將類似的配置節(jié)分到同一個(gè)組中。配置節(jié)組聲明部分將創(chuàng)建配置節(jié)的包含元素,在<configSections>元素中聲明配置節(jié)組,并將屬于該組的節(jié)置于<sectionGroup>元素中。下面是一個(gè)包含配置節(jié)組的配置文件的例子:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="TestGroup" > <section name="Test" type="System.Configuration.NameValueSectionHandler"/> </sectionGroup> </configSections> <TestGroup> <Test> <add key="Hello" value="World"/> </Test> </TestGroup>
下面是訪問這個(gè)配置節(jié)組的代碼:
NameValueCollectionnc=(NameValueCollection)ConfigurationSettings.GetConfig("TestGroup/Test"); MessageBox.Show(nc.AllKeys[0].ToString()+""+nc["Hello"]); //輸出HelloWorld