7

実行時にデフォルトファイル以外の別のファイルから設定をロードする方法はありApp.configますか? デフォルトの構成ファイルがロードされた後にこれを行いたいと思います。

Settings.SettingsVisual 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()

これが他の誰かを助けることを願っています!

4

3 に答える 3

1

アプリケーションのタイプによって異なります。

  1. Web アプリケーションと Windows アプリケーション - アプリケーションと同じフォルダー (またはサブフォルダー) に構成ファイルを保存する場合は、 configSource xml 属性を使用します。
  2. 設定プロバイダーを作成し、IApplicationSettingsProviderも実装します。サンプルはこちらこちらIConfigurationManagerInternalインターフェイスを使用して、既定の .NET 構成マネージャーを置き換える必要がある場合もあります。プロバイダーを実装するときは、ユーザー設定とアプリケーション設定、およびローミング プロファイルを区別することを忘れないでください。

すぐに始めたい場合は、LocalFileSettingsProviderクラス (既定の設定プロバイダー) を逆コンパイルして、必要に応じて変更します (いくつかの使いやすいコードが見つかり、依存するすべてのクラスを複製する必要がある場合があります)。

幸運を

于 2012-07-30T19:02:58.563 に答える
1

ExeConfigurationFileMap と ConfigurationManager.OpenMappedExeConfiguration の使用を見てください。

.Net 2.0 構成の謎の解明を参照してください。

ExeConfigurationFileMap を使用すると、OpenMappedExeConfiguration() を呼び出すときに、マシン、exe、ローミング、およびローカル構成ファイルへの正確なパス名をすべて一緒に、または少しずつ構成することができます。すべてのファイルを指定する必要はありませんが、Configuration オブジェクトの作成時にすべてのファイルが識別され、マージされます。OpenMappedExeConfiguration を使用する場合、要求したレベルまでの構成のすべてのレベルが常にマージされることを理解することが重要です。カスタム exe およびローカル構成ファイルを指定し、マシンおよびローミング ファイルを指定しない場合、既定のマシンおよびローミング ファイルが検出され、指定された exe およびユーザー ファイルとマージされます。指定されたファイルがデフォルトのファイルと適切に同期されていない場合、これは予期しない結果をもたらす可能性があります。

于 2012-07-30T18:56:38.493 に答える
0

毎回手動でソースを更新する必要がないように、型を含めることができます。

`private void LoadSetting(System.Xml.Linq.XElement setting) { string name = null, type = null; 文字列値 = 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)
            {
                if (this[name].GetType() == typeof(System.Collections.Specialized.StringCollection))
                {
                    foreach (string s in xValue.Element("ArrayOfString").Elements())
                    {
                        if (!((System.Collections.Specialized.StringCollection)this[name]).Contains(s))
                            ((System.Collections.Specialized.StringCollection)this[name]).Add(s);
                    }
                }
                else
                {
                    value = xValue.Value;
                }

                if (this[name].GetType() == typeof(int))
                {
                    this[name] = int.Parse(value);
                }
                else if (this[name].GetType() == typeof(bool))
                {
                    this[name] = bool.Parse(value);
                }
                else
                {
                    this[name] = value;
                }

            }
        }`
于 2013-07-16T10:30:25.703 に答える