Как получить ApplicationSettings из загруженного файла App.config?

Возможно ли получить доступ к значениям из раздела applicationSettings загруженного файла app.config?

Я нашел пример Как получить appSettings, но я не могу узнать, как получить доступ к applicationSettings таким образом.

Ответ 1

applicationSettings - readonly во время выполнения. Вы можете установить/изменить их либо с помощью текстового редактора в файле app.config напрямую, но рекомендуется открыть свойства проекта в Visual Studio и выбрать вкладку "Настройки". Важно установить правильную область действия:

  • Если настройки применяются ко всему приложению (для всех пользователей), выберите "Приложение" как область действия.
  • Если каждый пользователь должен иметь индивидуальные настройки (привязанные к профилю пользователя), выберите "Пользователь"

Например, если вы создаете myOwnSetting в своем проекте WindowsFormsTestApplication1 следующим образом:

myOwnSetting

он добавит следующее в файл приложения app.config:

<configuration>
    <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="WindowsFormsTestApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
    </configSections>
    <applicationSettings>
        <WindowsFormsTestApplication1.Properties.Settings>
            <setting name="myOwnSetting" serializeAs="String">
                <value>Hi there!</value>
            </setting>
        </WindowsFormsTestApplication1.Properties.Settings>
    </applicationSettings>
</configuration>

Visual Studio создает код С# для автоматического доступа к этому параметру (поэтому вы должны делать это в свойствах проекта, а не через текстовый редактор) - после того, как вы сохранили изменения, из одного и того же пространства имен вы можете прочитать его значение в приложение легко через следующий код:

var currentValue = Properties.Settings.Default.myOwnSetting;

Учитывая applicationSettings в приведенном выше списке, это приведет к восстановлению строки "Привет!". для переменной currentValue.

Примечание, если вы создали myOwnSetting для "Пользовательской" области, тогда он сохраняется в разделе с именем <userSettings> из <applicationSettings>, но вы все равно можете получить к нему доступ с помощью строки кода выше.

Другим отличием параметров области "Пользователь" является то, что у вас есть доступ на чтение и запись, то есть разрешено делать следующее:

        Properties.Settings.Default.myUserSetting = "Something else";
        Properties.Settings.Default.Save();

Если вы попробуете то же самое с параметром области "Приложение" myOwnSetting, это приведет к ошибке времени компиляции, сообщающей вам, что она доступна только для чтения.

Если вы заново запустите приложение, вы заметите, что myUserSetting изменилось на значение "Something else", но старое значение все еще находится в app.config. Почему это так? Причина в том, что он считается значением по умолчанию - и, как я сказал ранее, область "Пользователь" привязана к профилю пользователя. Как следствие, значение "Что-то еще" хранится в

C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0

в файле с именем User.config, который выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <WindowsFormsTestApplication1.Properties.Settings>
            <setting name="myUserSetting" serializeAs="String">
                <value>Something else</value>
            </setting>
        </WindowsFormsTestApplication1.Properties.Settings>
    </userSettings>
</configuration>

Вы не можете точно указать путь, поскольку он автоматически создается .NET Framework, и он будет выглядеть по-другому на вашем ПК. Но вы можете видеть, что USERID - это идентификатор пользователя Windows вашего текущего пользователя, FIRMNAME является частью указанной вами информации о сборке, а имя и версия сборки также используются в пути.


Примечание:

  • Объявление <sectionGroup> с <section> является обязательным, и его атрибут имени должен соответствовать пространству имен. Пространство имен должно отображаться ровно один раз в конфигурации, и разрешена только одна applicationSettings.

  • Как вы могли видеть в конфигурационном файле, пространство имен указано явно там (WindowsFormsTestApplication1.Properties.Settings). Как следствие, если вы хотите получить доступ к настройкам из кода, который не находится в одном и том же пространстве имен, вам может потребоваться использовать полностью квалифицированную ссылку. Сказав это, будьте осторожны, если вы скопируете весь раздел <applicationSettings>...</applicationSettings> из одного конфигурационного файла приложения в другой - вам может потребоваться впоследствии изменить пространство имен в целевой конфигурации.

  • Если вы используете конструктор настроек (вкладка "Параметры" в своем проекте), он создаст файл с именем Settings.Settings (вместе с Settings.Designer.cs для доступа к сеансам через С# кода) в разделе "Свойства" вашего проекта. Это копия настроек, так как она будет храниться в вашем файле Web.config или App.config (в зависимости от вашего типа проекта, только для параметров области приложения - настройки области пользователя сохраняются на основе профиля пользователя). Вы можете создать дополнительные файлы *.settings и использовать их (как описано здесь).

  • Если вы используете не с помощью конструктора параметров или используете инструмент, например LinqPad, вам может потребоваться использовать другой подход. Рассмотрим это:

    internal static string GetApplicationSetting(string key, 
            string nameSpace="Properties.Settings")
    {
        string xValue=null;
        try 
        {
            string path = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            XDocument doc = XDocument.Load(path);
            var xPathStr= string.IsNullOrEmpty(nameSpace) 
                            ? "//applicationSettings" 
                            : $"//applicationSettings/{nameSpace}";
            var settings=doc.XPathSelectElement(xPathStr).Elements().Where(
                                w => w.Name=="setting" 
                                    && w.HasAttributes 
                                    && w.Attribute("serializeAs").Value=="String"
                                );
            var setting=settings.Where(f => f.HasAttributes 
                                            && f.Attribute("name").Value==key).Elements();
            xValue=setting.FirstOrDefault().Value;
        }
        catch {}
        return xValue;
    }
    

    Вы можете прочитать тип строки applicationSettings, рассматривая конфигурацию как XDocument. Приведенный пример ограничен строковым типом, и вы можете извлечь параметр из примера app.config выше:
    var value=GetApplicationSetting("myOwnSetting", "WindowsFormsTestApplication1.Properties.Settings");
    Аналогично, вы можете создать аналогичную функцию GetUserSetting для раздела <userSettings> по умолчанию: просто скопируйте приведенный выше код, переименуйте имя функции и замените applicationSettings на xPathStr на userSettings.

  • Существует метод обновления, доступный для пользовательских настроек, который описан здесь. Более подробную информацию о местоположении, где хранятся пользовательские настройки, можно найти там.

  • Раздел <appSettings> в конфигурации работает по-разному, поскольку он не различает область "Пользователь" и "Приложение" и не поддерживает разные типы данных, просто строки. Тем не менее, можно легко читать и писать ключи/значения конфигурации. Если вас интересует код, вы можете найти его здесь (в stackoverflow):
    как читать/записывать настройки конфигурации appSettings

  • Если вы не уверены, следует ли использовать AppSettings или applicationSettings, тогда прочитать это, прежде чем вы решите.

Ответ 2

Как вы создали настройки? Используя конструктор настроек VS? Если это так, он должен создать для вас строго типизированный класс. Обычно это делается с помощью Properties.Settings.Default.SettingName

Я думаю, что предпочтительнее использовать applicationSettings, а не appSettings, но параметры приложения обновляются только во время выполнения, т.е. вы не можете их создать из своего кода, но можно создать и добавить appSettings во время выполнения, я считаю. Я задал вопрос о разнице

вы можете найти дополнительную информацию из msdn

Ответ 3

Вы можете загрузить файл конфигурации в XmlDocument и загрузить приложениеSettings   из объекта dom.   Вот пример, который я нашел, чтобы загрузить файл конфигурации в объект dom:

//retrive the current assembly directory
private static string AssemblyDirectory()
{
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
}



//return the value from aplicationSetting according to the given key
//appSettingSection is the your configuration section as declare in your web.config
public static string GetApplicationSettingValue(string appSettingSection,string key)
{
   //get web.config path
   string configPath  = new System.IO.DirectoryInfo(AssemblyDirectory()).Parent.FullName + "\\web.config";

    System.IO.FileInfo FileInfo = new System.IO.FileInfo(configPath);
    if (!FileInfo.Exists)
    {
        throw new Exception("Missing config file");
    }

    //load config file into xml document
    var XmlConfig = new System.Xml.XmlDocument();
    XmlConfig.Load(FileInfo.FullName);


     //override xml document and return the value of the key under applicationSettings
     foreach (System.Xml.XmlNode node in XmlConfig["configuration"]  ["applicationSettings"]appSettingSection])
     {
                    if (node.Name == "setting")
                    {
                        if (node.Attributes.GetNamedItem("name").Value == key)
                        {
                            return node.FirstChild.InnerXml.ToString();
                        }
                   }
     }
   return "";
}