C# ConfigurationManager 多個配置文件讀取問題


之前寫了篇通過Winform程序管理Windows Service 服務的文章,后來在實際使用過程中,將一些需要修改的參數順手就寫到了配置文件App.config里面。然后直接F5運行項目,想着調試下看看程序是否正常運行,這一試就試出問題了,ConfigurationManager.AppSettings.Get("message")獲取不到參數。

ConfigurationManager

ConfigurationManager是一個提供對客戶端應用程序配置文件訪問的靜態類,此類不能被繼承。使用此類需要先將System.Configuration.dll引用到項目中來,具體的使用方式建議查看官方文檔

回顧一下上文項目的目錄結構,在一個解決方案中有兩個項目分別為TaskWindowsService(Windows服務項目)和WindowsServiceClient(服務管理winform程序)。他們都有各自的App.config文件。

接下來我們做一個測試:

  1. 各個項目的App.config中分別添加如下代碼
<appSettings>
	<add key="message" value="this is TaskWindowsService"/>
</appSettings>

<appSettings>
	<add key="message" value="this is WindowsServiceClient"/>
</appSettings>

ps:(兩個配置文件都有了,總不至於讀不到數據了吧~)

  1. 在TaskWindowsService中引用System.Configuration.dll,並使用ConfigurationManager讀取配置文件,記錄到日志中
public static void ConfigTest()
{
    LogHelper.Log(ConfigurationManager.AppSettings.Get("message"));
}
  1. 運行WindowsServiceClient並調用ConfigTest()方法
public Form1()
{
    InitializeComponent();
    SkpDomain.ConfigTest();
}
  1. 注冊並啟動TaskWindowsService 在服務啟動時調用ConfigTest()方法
protected override void OnStart(string[] args)
{
    SkpDomain.ConfigTest();
}

看一下輸出的日志,好玩的東西來了。居然兩個app.config文件都光顧到了。從順序來看,先打開讀取的是WindowsServiceClient的配置文件,再是TaskWindowsService啟動時讀取的配置文件。

{"Time":"2020-10-28 17:38:55","Message":"this is WindowsServiceClient","Data":null}
{"Time":"2020-10-28 17:38:57","Message":"this is TaskWindowsService","Data":null}

從這里可以得出一個結論:ConfigurationManager讀取的配置文件是由當前運行的項目決定的

這里引用一段

app.config, *.exe.config 和 *.vshost.exe.config區別

引用自 https://www.cnblogs.com/leenice/p/5286451.html

1. app.config

作為開發時配置參數的文件,可以在vs開發時右鍵屬性設置是否復制到可執行程序同目錄下(默認始終不復制)。
在不復制的情況下,編譯生成可執行程序時會copy該文件為.exe.config文件和.vshost.exe.config文件。

這樣的話,在/bin/debug/ 或者/bin/release/目錄下就不會有app.config文件了,對應的有exe.config和vshost.exe.config。

以后運行exe文件所操作的配置文件(通過System.Configuration對象,System.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None))直接修改的是exe.config文件。

2.*.exe.config

vs調試編譯時,如果app.config文件有修改,則會重新copy覆蓋到exe.config和vshost.exe.config文件中,
否則exe.config不會改變。exe.config文件為程序實際運行時(直接運行.exe程序)直接操作的配置文件。

3.*.vshost.exe.config

該文件主要是在vs調試運行時起作用,在調試運行程序時(*vshost.exe -> *.exe)先copy *.exe.config覆蓋
*.vshost.exe.config,然后運行程序時操作的配置文件為 .vshost.exe.config。在調試程序結束時(.exe -> *.vshost.exe)再次copy .exe.config覆蓋.vshost.exe.config。 所以調試情況下無論怎么修改配置文件,程序退出后都不會修改配置文件(還原了)。


如果一定要強行指定獲取某一個程序的配置文件,可以這么做:

public static void ConfigTest()
{
    var servicePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskWindowsService.exe");//一定是運行程序路徑,而不是配置文件路徑
    LogHelper.Log(ConfigurationManager.OpenExeConfiguration(servicePath).AppSettings.Settings["message"].Value);
}

總結

問題不大,這個坑以前也踩過,但是沒有仔細的研究背后的原因,只是在兩個配置文件中都寫了一樣的參數,事情過了也就忘了。這次重新遇到就好好記錄一下,以后可不能再踩坑了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM