標籤:int bug 程式 sse bre manage pen 方案 相對
作普通的xml檔案讀取的話,首先就要知道怎麼尋找檔案的路徑。我們知道一般設定檔就在跟可執行exe檔案在同一目錄下,且僅僅在名稱後面添加了一個.config 因此,可以用Application.ExecuteablePath+".cofig"的方式來獲得,不過更加推薦使用AppDomain.CurrentDomain.SetupInformation.ConfigurationFile這句話來直接擷取當前程式的設定檔的位置,具體原因,後面再敘述。
現在回過頭還是看上面的這個函數,看它的最後一行,它的作用是什嗎?
尋找msdn文檔可以發現微軟出於效能考慮,對設定檔App.config採用了緩衝策略,因此,儘管上面的函數確實在磁碟檔案中修改了節點的值,但是,當用前面的那個函數讀取的時候,會依然得到原來的那個值,彷彿沒有修改一樣!所以,必須使用這麼句話,進行一遍重新整理,強制要求程式下一次讀取的時候,從磁碟檔案讀取!
好了,現在使用Visual Studio寫C#程式的童鞋應該都遇到了一個蛋疼的問題,就是在debug時,明明在程式中修改了設定檔,可是下次重新執行程式的時候,發現程式根本沒有發生變化,開啟與exe檔案相對應的config檔案查看,發現檔案根本沒有變化!!!!明明就是當作xml檔案來操作的,怎麼會這樣?!
其實這就涉及VS的運行機制問題了,細心的童鞋會在exe檔案的同目錄下,發現有一個與之對應的vshost.exe,以及vshost.exe.config 檔案,當開啟這裡的這個config檔案後會發現,在這裡面的xml檔案的值發生了變化!對滴~VS無論在Debug還是Release下,啟動並執行程式都是這個帶有vshost的程式,修改的也是這個程式對應的config。當程式剛剛啟動的時候,卻是讀取的原來與exe檔案對應的config檔案,將這個config檔案內容替換原來與vshost.exe對應的config裡面內容,這也就是為什麼每次重新開程式後恢複原狀的原因。
由於程式在VS裡面調試的時候,啟動並執行程式與直接去bin檔案夾啟動並執行程式不一樣,所以,更推薦使用AppDomain.CurrentDomain.SetupInformation.ConfigurationFile來擷取當前運行程式的設定檔。
用了各種方法 ,還是無法修改App.config的內容,雖然vshost.exe.config 確實修改。但是下一次啟動讀的還是原來的config,並且還替換了已經修改的vshost.exe.config
最終採取的方案如下:
public class AppConfigHelper { public static string GetValueByKey(string key) { ConfigurationManager.RefreshSection("appSettings"); return ConfigurationManager.AppSettings[key]; } public static void ModifyAppSettings(string strKey, string value) { //獲得設定檔的全路徑 var assemblyConfigFile = Assembly.GetEntryAssembly().Location; var appDomainConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; ChangeConfiguration(strKey, value, assemblyConfigFile); ModifyAppConfig(strKey, value, appDomainConfigFile); } private static void ModifyAppConfig(string strKey, string value, string configPath) { var doc = new XmlDocument(); doc.Load(configPath); //找出名稱為“add”的所有元素 var nodes = doc.GetElementsByTagName("add"); for (int i = 0; i < nodes.Count; i++) { //獲得將當前元素的key屬性 var xmlAttributeCollection = nodes[i].Attributes; if (xmlAttributeCollection != null) { var att = xmlAttributeCollection["key"]; if (att == null) continue; //根據元素的第一個屬性來判斷當前的元素是不是目標元素 if (att.Value != strKey) continue; //對目標元素中的第二個屬性賦值 att = xmlAttributeCollection["value"]; att.Value = value; } break; } //儲存上面的修改 doc.Save(configPath); ConfigurationManager.RefreshSection("appSettings"); } public static void ChangeConfiguration(string key, string value, string path) { var config = ConfigurationManager.OpenExeConfiguration(path); config.AppSettings.Settings.Remove(key); config.AppSettings.Settings.Add(key, value); config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); } }
雖說 app.config檔案 還是無法看到修改,但是程式啟動並執行時候實際調用的兩個檔案(vshost.exe.config和exe.config )都被修改了,這樣每次啟動 設定檔裡的內容也都是最新的,只不過如果你的程式重建的話,兩個檔案就會被app.config的內容覆蓋。
僅僅是調式階段會有一些不方便,但是一旦打包,就能夠很好的使用,每次都能修改設定檔內容,並讀取到最新的內容。
設定檔——App.config檔案讀取和修改