VS動態修改App.config中遇到的坑(宿主進程問題)
昨天遇到了很奇怪的一個bug,具體描述如下:
這個系統是c/s架構的針對多個工廠做的資材管理系統,由於有很多個工廠,每個工廠都有自己的服務器。所以需要動態的改變連接字符串去鏈接不同的服務器。
由於這個連接字符串放在了app.config文件中,所以公司上一個開發人員設置為,當選擇不同公司時會讓程序關閉然後去更新配置文件。近來由於公司要求,不想讓程序重啟然後去改變配置文件。
原本的解決方案是當下拉框發生改變的時候,重新向新的服務器發送請求獲取數據。
但是出現了一個問題,就是項目中所用的dataset中綁定的連接字符串不會實時獲取新的連接字符串。
也就是程序中對app.config的修改沒有立馬產生作用。
經過一上午的測試與查找資料,找到問題發生的原因及解決方案。
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"); }
關於宿主進程的詳細測試如下:
用宿主進程和不用宿主進程進行調試的一些差異
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,它將返回該應用程序名。
VS動態修改App.config中遇到的坑(宿主進程問題)