昨天遇到了很奇怪的一個bug,具體描述以下:安全
這個系統是c/s架構的針對多個工廠作的資材管理系統,因爲有不少個工廠,每一個工廠都有本身的服務器。因此須要動態的改變鏈接字符串去連接不一樣的服務器。服務器
因爲這個鏈接字符串放在了app.config文件中,因此公司上一個開發人員設置爲,當選擇不一樣公司時會讓程序關閉而後去更新配置文件。近來因爲公司要求,不想讓程序重啓而後去改變配置文件。架構
本來的解決方案是當下拉框發生改變的時候,從新向新的服務器發送請求獲取數據。app
可是出現了一個問題,就是項目中所用的dataset中綁定的鏈接字符串不會實時獲取新的鏈接字符串。測試
也就是程序中對app.config的修改沒有立馬產生做用。
通過一上午的測試與查找資料,找到問題發生的緣由及解決方案。spa
VS2005之後,會默認生成VS宿主進程,在項目的屬性 的調試項目下的一個選項。
當啓用這個功能後,在程序中對app.config所作的操做不會實時改變,而是修改*.exe.config和*.Vhost.Config,並不會直接修改App.config設計
解決方法是禁用掉這一個選項,並在修改app.config方法中添加對配置文件的刷新調試
/// <summary> /// 修改 app.config 中 connectionStrings 的方法 /// </summary> /// <param name="AppKey"></param> /// <param name="AppValue"></param> public void SetConfigValue(string keyName, string conStr) { XmlDocument xDoc = new XmlDocument(); //獲取可執行文件的路徑和名稱 xDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config"); XmlNode xNode; XmlElement xElem1; XmlElement xElem2; xNode = xDoc.SelectSingleNode("//connectionStrings"); xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@name='" + keyName + "']"); if (xElem1 != null) xElem1.SetAttribute("connectionString", conStr); else { xElem2 = xDoc.CreateElement("add"); xElem2.SetAttribute("name", keyName); xElem2.SetAttribute("connectionString", conStr); xNode.AppendChild(xElem2); } xDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config"); ConfigurationManager.RefreshSection("connectionStrings"); }
關於宿主進程的詳細測試以下:code
用宿主進程和不用宿主進程進行調試的一些差別orm
1) 部分信任調試和 Click-Once 安全
部分信任調試須要宿主進程。若是禁用宿主進程,部分信任調試將不工做,即便在「項目屬性」的「安全」頁上啓用了部分信任安全。
2) 設計時錶達式計算
設計時錶達式始終使用宿主進程。若是在「項目屬性」中禁用宿主進程,則禁用了類庫項目的設計時錶達式計算。對於其餘項目類型,不由用設計時錶達式計算。相反,Visual Studio 啓動實際可執行文件,並將它用於不用宿主進程的設計時計算。這種差別可能產生不一樣的結果。
3) AppDomain.CurrentDomain.FriendlyName 差別
AppDomain.CurrentDomain.FriendlyName 依據是否啓用宿主進程返回不一樣的結果。若是啓用宿主進程時調用 AppDomain.CurrentDomain.FriendlyName,它將返回 app_name.vhost.exe。若是禁用宿主進程時調用它,它將返回 app_name.exe。
4) Assembly.GetCallingAssembly().FullName 差別
Assembly.GetCallingAssembly().FullName 依據是否啓用宿主進程返回不一樣的結果。若是啓用宿主進程時調用 Assembly.GetCallingAssembly().FullName,它將返回 mscorlib。若是禁用宿主進程時調用 Assembly.GetCallingAssembly().FullName,它將返回該應用程序名。