1. 程式人生 > >VS動態修改App.config中遇到的坑(宿主進程問題)

VS動態修改App.config中遇到的坑(宿主進程問題)

void get 針對 bug 圖片 解決方案 很多 選項 sco

昨天遇到了很奇怪的一個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中遇到的坑(宿主進程問題)