1. 程式人生 > 實用技巧 >C#下.NET配置檔案的使用(1)

C#下.NET配置檔案的使用(1)

原文連結:https://blog.csdn.net/dbzhang800/article/details/7212420

System.Configuration 名稱空間中的東西是為讀寫應用程式的配置資料服務的。

在Windows早期,程式使用 .ini 作為配置檔案,後來開始鼓勵大家使用登錄檔,到了.NET中,又迴歸到使用檔案,只不過這次預設是xml格式的檔案。

例子

程式program.exe預設配置檔案 program.exe.config 中的 "appSettings" 段

讀寫program.exe.config 中的 "appSettings" 段

讀寫program.exe.config 中的自定義欄位 "QtSection"

讀寫roaming 檔案中的自定義欄位"QtSection"

讀寫任意位置的配置檔案?

例子一

  • 配置檔案 program.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <appSettings>
    <add key="first name" value="Debao" />
    <add key="last name
" value="Zhang" /> </appSettings> </configuration>
  • 程式原始碼 program.cs
using System.Configuration;

namespace DbZhang800
{
    public class TestSettings
    {
        public static void Main()
        {
            foreach (string key in ConfigurationManager.AppSettings)
            {
                
string val = ConfigurationManager.AppSettings[key]; Console.WriteLine("{0}: {1}", key, val); } } } }

編譯執行,結果如下:

E:\> csc program.cs
E:\> program.exe
first name: Debao
last name: Zhang

通過ConfigurationManager.AppSettings我們可以很方便地讀取預設配置檔案中的 appSettings 段。

例子二

前面是隻讀的,如果需要寫入怎麼辦?

            Configuration appConf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            appConf.AppSettings.Settings.Add("Qt", "Quick");
            appConf.Save();

編譯執行(注,這是執行3次後的結果,每次都給Qt這個key增加了一項):

E:\> csc program.cs
E:\> program.exe
first name: Debao
last name: Zhang
Qt: Quick,Quick,Quick

此時的配置檔案 program.exe.config 內容如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <appSettings>
     <add key="first name" value="Debao" />
     <add key="last name" value="Zhang" />
     <add key="Qt" value="Quick,Quick,Quick" />
 </appSettings>
</configuration>

例子三

看看讀寫自定義欄位的情況。不操作appSettings,操作一個自定義的QtSection段

program.cs

  • 首先建立一個ConfigurationSection的派生類

  • 然後開啟一個配置檔案,通過該派生類進行操作
using System;
using System.Configuration;

namespace DbZhang800
{
    public sealed class QtSection : ConfigurationSection
    {
        [ConfigurationProperty("version", DefaultValue="4.4.0")]
        public string Version
        {
            get
            {
                return (string)this["version"];
            }

            set
            {
                this["version"] = value;
            }
        }
    }

    public class TestSettings
    {
        public static void Main()
        {
            Configuration appConf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            QtSection qtsection;
            if ((qtsection = (QtSection)appConf.Sections["QtSection"]) == null)
            {
                qtsection = new QtSection();
                //qtsection.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
                appConf.Sections.Add("QtSection", qtsection);
            }
            Console.WriteLine("Current: {0}", qtsection.Version);
            qtsection.Version = "5.0.0";
            appConf.Save(ConfigurationSaveMode.Full);
        }
    }
}

執行後,生成的配置檔案如下:

program.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
     <section name="QtSection" type="DbZhang800.QtSection, Program, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" overrideModeDefault="Allow" restartOnExternalChanges="true" requirePermission="true" />
 </configSections>
 <QtSection version="5.0.0" />
</configuration>

注意:它在configSections自動添加了我們自定義段的一些資訊。

例子四

前面的配置檔案和應用程式在同一個目錄下,如果不同使用者需要不同的配置檔案怎麼辦呢?

前面的例子中,OpenExeConfiguration使用的引數是 None,該引數指定不同的級別

None

只使用程式預設配置檔案

PerUserRoaming

也要使用使用者 roam 檔案

PerUserRoamingAndLocal

也要使用使用者local 檔案

在前一個例子基礎上,我們把 None 改為 PerUserRoaming看看,結果... 執行時:

E:\TestSettings>program.exe
Current: 5.0.0

未處理的異常:  System.Configuration.ConfigurationErrorsException: 執行 !QtSection
 的配置節處理程式時出錯。 ---> System.InvalidOperationException: 不能編輯已鎖定的
 ConfigurationSection 屬性。
...

報出異常,無法將其寫入到roaming檔案,原因何在呢?

  • 就在於我們在xml檔案看到的那個MachineToApplication屬性,該段只能寫入到machine和appplication級別的配置檔案,無法寫入使用者配置檔案。

我們需要在生成這個段的時候就新增一個 MachineToRoamingUser 屬性

       public static void Main()
        {
            Configuration appConf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming);
            QtSection qtsection;
            if ((qtsection = (QtSection)appConf.Sections["QtSection"]) == null)
            {
                qtsection = new QtSection();
                qtsection.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToRoamingUser;
                appConf.Sections.Add("QtSection", qtsection);
            }
            Console.WriteLine("Current: {0}", qtsection.Version);
            qtsection.Version = "5.0.0";
            Console.WriteLine(appConf.FilePath);
            appConf.Save(ConfigurationSaveMode.Full);
        }

這樣,配置可以正常寫入

C:\Users\dbzhang\AppData\Roaming\DbZhang800\Program.exe_Url_foycvmvcbx4tf51hrft53z11fmpo2kto\0.0.0.0\user.config

開啟其他的配置檔案:

  • ConfigurationManager.OpenExeConfiguration(string)

    • 這個東西,string 指定 exe 的路徑(但不限於,該路徑後會被自動新增一個 .config)
  • ConfigurationManager..::.OpenMachineConfiguration()

    • 位於%windir%\Microsoft.NET\Framework\version\config

例子五

操作其他的配置檔案

比如,我要操作當前工作目錄下的 abcd.config 這個檔案,那麼需要使用 OpenMappedExcConfiguration:

        public static void Main()
        {
            string path = System.IO.Path.Combine(Environment.CurrentDirectory, "abcd.config");
            ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
            configFile.ExeConfigFilename = path;
            Configuration appConf = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);

            QtSection qtsection;
            if ((qtsection = (QtSection)appConf.Sections["QtSection"]) == null)
            {
                qtsection = new QtSection();
                appConf.Sections.Add("QtSection", qtsection);
            }
            Console.WriteLine("Current: {0}", qtsection.Version);
            qtsection.Version = "5.0.0";
            appConf.Save(ConfigurationSaveMode.Full);
       }