実行時にデフォルトファイル以外の別のファイルから設定をロードする方法はありApp.config
ますか? デフォルトの構成ファイルがロードされた後にこれを行いたいと思います。
Settings.Settings
Visual Studioの GUI を使用してApp.config
ファイルを作成します。設定ファイルは最終的に次のようになります。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="SnipetTester.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<SnipetTester.Properties.Settings>
<setting name="SettingSomething" serializeAs="String">
<value>1234</value>
</setting>
</SnipetTester.Properties.Settings>
</applicationSettings>
</configuration>
コードでは、次のような設定にアクセスできます。
Console.WriteLine("Default setting value: " + Properties.Settings.Default.SettingSomething);
アプリケーションの実行時にProperties.Settings.Default
、デフォルト ファイルを使用する代わりに、実行時に構成ファイルを指定し、アプリケーションが構成ファイルをオブジェクトにロードできるようにする必要がありapp.config
ます。構成ファイルの形式は同じですが、設定の値は異なります。
でこれを行う方法を知っていConfigurationManager.OpenExeConfiguration(configFile);
ます。ただし、私が実行したテストでは、Properties.Settings.Default
構成ファイルからの新しい値を反映するようにオブジェクトを更新しません。
これについてもう少し考えた後、私はもう少し良い解決策を思いつくことができました. いくつかの落とし穴があると確信していますが、必要なことにはうまくいくと思います。
基本的に、Properties.Settings
クラスは Visual Studio によって自動的に生成されます。クラスのコードを生成します。コードが生成された場所を見つけ、いくつかの関数呼び出しを追加して構成ファイルを独自にロードすることができました。これが私の追加です:
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
//Parses a config file and loads its settings
public void Load(string filename)
{
System.Xml.Linq.XElement xml = null;
try
{
string text = System.IO.File.ReadAllText(filename);
xml = System.Xml.Linq.XElement.Parse(text);
}
catch
{
//Pokemon catch statement (gotta catch 'em all)
//If some exception occurs while loading the file,
//assume either the file was unable to be read or
//the config file is not in the right format.
//The xml variable will be null and none of the
//settings will be loaded.
}
if(xml != null)
{
foreach(System.Xml.Linq.XElement currentElement in xml.Elements())
{
switch (currentElement.Name.LocalName)
{
case "userSettings":
case "applicationSettings":
foreach (System.Xml.Linq.XElement settingNamespace in currentElement.Elements())
{
if (settingNamespace.Name.LocalName == "SnipetTester.Properties.Settings")
{
foreach (System.Xml.Linq.XElement setting in settingNamespace.Elements())
{
LoadSetting(setting);
}
}
}
break;
default:
break;
}
}
}
}
//Loads a setting based on it's xml representation in the config file
private void LoadSetting(System.Xml.Linq.XElement setting)
{
string name = null, type = null, value = null;
if (setting.Name.LocalName == "setting")
{
System.Xml.Linq.XAttribute xName = setting.Attribute("name");
if (xName != null)
{
name = xName.Value;
}
System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs");
if (xSerialize != null)
{
type = xSerialize.Value;
}
System.Xml.Linq.XElement xValue = setting.Element("value");
if (xValue != null)
{
value = xValue.Value;
}
}
if (string.IsNullOrEmpty(name) == false &&
string.IsNullOrEmpty(type) == false &&
string.IsNullOrEmpty(value) == false)
{
switch (name)
{
//One of the pitfalls is that everytime you add a new
//setting to the config file, you will need to add another
//case to the switch statement.
case "SettingSomething":
this[name] = value;
break;
default:
break;
}
}
}
}
追加したコードは関数を公開しProperties.Settings.Load(string filename)
ます。この関数は、構成ファイル名をパラメーターとして受け入れます。ファイルを解析し、構成ファイルで検出した設定をロードします。元の構成に戻すには、単に を呼び出しますProperties.Settings.Reload()
。
これが他の誰かを助けることを願っています!