【.net 深呼吸】在运行阶段修改应用配置文件
上一篇博文中,老周所介紹的自行編寫的配置類,雖然能夠很好地做封裝,但它僅允許修改用戶級(jí)別的配置,所以文件都是保存到用戶配置目錄下的。可是,許多情況下,我們還是不考慮用戶隔離,而是能夠直接修改與應(yīng)用程序同目錄的App.config文件。
那么,能不能在代碼文件中編輯 app.config 文件呢?當(dāng)然是可以的。其實(shí),配置文件本質(zhì)上是個(gè)XML文檔,所以,你是可以使用普通XML文件的編輯方式來修改的。但.net類庫還是提供有于讀寫配置文件的專用API,使用專用的API,使得生成的配置比較規(guī)范。
.net 的配置文件是由N個(gè)配置節(jié)組成,每個(gè)配置節(jié)面向不同的功能,比如?startup 可以配置程序所需要的.net 框架版本。為了便于管理,通常,咱們的應(yīng)用程序設(shè)置都會(huì)放到 AppSettings 節(jié)上,XML節(jié)點(diǎn)為?appSettings。每一條配置都比較簡(jiǎn)單,就是由 key 和 value 組成。
要對(duì)配置文件進(jìn)行操作,你記得要引用?System.Configuration.dll 程序集,因?yàn)镾ystem程序集只包含一些常規(guī)的類型,而專用于讀寫配置文件的類型都會(huì)包裝到?System.Configuration 程序集中。這些API既適用于app.config,也適用于web.config文件。
好,上面這幾段廢話只要你看懂了,那么下面我們就可以開始干活了。放心,很簡(jiǎn)單的,老周給你分享的東西,向來都是簡(jiǎn)單且有實(shí)用價(jià)值的。
?
首先,老周介紹一下大概的類型使用過程。
讀——讀取 app.config 文件中 appSettings 節(jié)中的內(nèi)容很簡(jiǎn)單,使用?ConfigurationManager 類,它公開了兩個(gè)靜態(tài)屬性,別小看它們,有了這兩個(gè)屬性,讀取配置會(huì)輕松很多。ConnectionStrings:做過數(shù)據(jù)庫連接的話,你肯定很熟悉它的,這個(gè)節(jié)點(diǎn)下專門存放連接字符串;AppSettings:這個(gè)專門訪問 appSettings 節(jié)點(diǎn)下的內(nèi)容,表示形式很簡(jiǎn)潔,就是key - value 對(duì),而且都是字符串類型。
寫——寫入修改會(huì)稍稍復(fù)雜一點(diǎn),但也不是難題。
? a、ConfigurationManager類有個(gè)靜態(tài)方法?OpenExeConfiguration ,你可以指定exe文件路徑,它自動(dòng)找到匹配的app.config文件,然后打開,返回一個(gè)?Configuration 類型的實(shí)例。
? b、Configuration 類可以對(duì)配置文件進(jìn)行修改,修改完后,可以掉用 Save 方法保存,或調(diào)用 SaveAs 方法把配置存到其他文件上。
?
接下來,老周上一個(gè)例子,這個(gè)例子運(yùn)行后,在窗口上可以設(shè)置電腦自爆的日期,當(dāng)窗口關(guān)閉時(shí)會(huì)把這個(gè)日期寫入配置文件中的appSettings 節(jié)點(diǎn)下。如下圖所示。
?
?跟你開個(gè)玩笑而已,計(jì)算機(jī)不會(huì)真的爆炸。
通常,我們會(huì)在窗口加載時(shí)讀出配置文件中的值,以便在界面上顯示用戶上一次設(shè)置的內(nèi)容,不然用戶會(huì)誤以為配置丟失。
var q = ConfigurationManager.AppSettings.AllKeys.AsQueryable();var r = from c in q where c == BOMB_DATE select c;if (r.Count() > 0){string datestr = ConfigurationManager.AppSettings[BOMB_DATE];picker.SelectedDate = DateTime.Parse(datestr);}在讀應(yīng)用配置前,我用 LINQ 語句查詢了一下,確認(rèn)我要訪問的設(shè)置項(xiàng)是否存在,如果沒有要的設(shè)置項(xiàng),那讀個(gè)雞毛。設(shè)置節(jié)的key是用字符串來表示的,BOMB_DATE是我定義的一個(gè)常量。
const string BOMB_DATE = "bombDate";配置文件中的設(shè)置值是以字符串形保存的,而咱們窗口上的控件需要的是 DateTime 類型的實(shí)例,所以讀出來后記得要 Parse 一下。
?
接下來,我們?cè)倏纯慈绾涡薷牟⒈4?app.config 文件。
先把日期選擇控件中用戶選擇的日期轉(zhuǎn)為字符串。
DateTime seldate = picker.SelectedDate ?? DateTime.Today;string forstr = seldate.ToShortDateString();?
然后,還得獲取當(dāng)前程序的exe路徑。
string exePath = Environment.GetCommandLineArgs()[0];GetCommandLineArgs 方法返回的字符串?dāng)?shù)組中,第一個(gè)元素就是本程序exe的路徑。
?
調(diào)用?ConfigurationManager.OpenExeConfiguration 靜態(tài)方法打開app.config文件。
Configuration config = ConfigurationManager.OpenExeConfiguration(exePath);?
隨后,是重點(diǎn)部分,就是寫入設(shè)置內(nèi)容。
if (config.AppSettings.Settings.AllKeys.Count(s => s == BOMB_DATE) > 0){// 如果設(shè)置項(xiàng)已經(jīng)存在// 則直接修改var kv = config.AppSettings.Settings[BOMB_DATE];kv.Value = forstr;}else{// 如果設(shè)置項(xiàng)不存在// 則添加新項(xiàng) config.AppSettings.Settings.Add(BOMB_DATE, forstr);}這里有個(gè)很嚴(yán)重的內(nèi)容,大家一定、必須、特別要注意。得判一下設(shè)置項(xiàng)的key是否已存在,因?yàn)槟闳绻苯诱{(diào)用 Add 方法添加的話,如果設(shè)置項(xiàng)的key已存在,它不是替換整個(gè)值,而是會(huì)在原來的值后面追加內(nèi)容。
比如在本例中,要是我寫入了 2017/10/1,第一次保存,因?yàn)樵O(shè)置項(xiàng)不存在,所以沒問題。但是,一旦我把值修改為 2017/11/5,然后再保存,那么設(shè)置項(xiàng)的值 就會(huì)變?yōu)?/p> 2017/10/1,2017/11/5
也就是說,新保存的內(nèi)容不會(huì)替換,而是追加,然后用逗號(hào)分隔每個(gè)值。
如此一來,在讀取的時(shí)候就麻煩了,這樣的字符串是不能轉(zhuǎn)化為 DateTime 實(shí)例的。
?
所以,這里要先分析一下,如果設(shè)置項(xiàng)已經(jīng)存在,那就通過索引器得到這個(gè)設(shè)置項(xiàng)的內(nèi)容,它用一個(gè)?KeyValueConfigurationElement 類封裝,其中,Value 屬性是可以修改的(Key不能變,所以只讀),此時(shí),我們只要直接給 Value 屬性賦新的值,那么保存時(shí)就會(huì)覆蓋原有的值,而不會(huì)在后面追加了。而如果設(shè)置項(xiàng)不存在,那太好辦,直接一個(gè)Add方法添加就可以了。
?
最后,修改完了,別忘了保存,不保存的話,是不會(huì)寫入app.config文件的。
if (config.AppSettings.SectionInformation.IsLocked){// 如果配置節(jié)已鎖定,則放棄保存return;}config.Save(ConfigurationSaveMode.Modified);保存前檢測(cè)?IsLocked 屬性,是看看這個(gè)配置節(jié)是否被鎖定,如果鎖了,你是不能保存的。
在配置文件中,你可以用這種方法來讓某個(gè)節(jié)點(diǎn)被鎖定。
<appSettings lockItem="true">……</appSettings>
鎖定后,節(jié)點(diǎn)就不允許別人編輯了。當(dāng)然了,你手動(dòng)打開配置文件是可以改的,我說的是在代碼中用API不能改。
?
在調(diào)用?Configuration 實(shí)例的 Save 方法時(shí),可以向方法傳遞一個(gè)?ConfigurationSaveMode 枚舉值,這里我用?Modified,表示只對(duì)被修改過的節(jié)點(diǎn)進(jìn)行寫入,這樣做可以省時(shí)省力省開銷。
?
保存后的 app.config 文件的appSettings節(jié)點(diǎn)如下。
<appSettings><add key="bombDate" value="2017/7/28" /></appSettings>?
=================================================
以上示例的源代碼下載,請(qǐng)點(diǎn)擊?這里?
?
怎么樣,學(xué)了后有用吧。差點(diǎn)忘了說,如果你把exe文件放在如 Program Files 等需要管理員權(quán)限的目錄中,你必須以管理員身份運(yùn)行應(yīng)用程序才能保存配置文件。
?
總結(jié)
以上是生活随笔為你收集整理的【.net 深呼吸】在运行阶段修改应用配置文件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。