c # forms — программно добавлять недостающие записи в файл .config

#c# #forms #settings #app-config

#c# #формы #Настройки #app-config

Вопрос:

вопрос, на который я не нашел ответа после долгого поиска в Google (затем долгий перерыв и повторный поиск)…

Скажем, у меня есть 2 параметра в настройках моего приложения. String1 и String2. Скажем, далее, мы отправили продукт и начали добавлять второстепенные функции (больше вещей для настройки), и мы добавляем String3 . Как, не обходя файл .config вручную, я могу добавить недостающие записи? При отправке в качестве обновления (кстати, без OneClick.) существующий файл .config содержит только String1 и String2.

При использовании по умолчанию String3 приложение каким-то образом понимает, что запись отсутствует, поэтому должно быть возможно, или я так думаю, добавить этот параметр со значением по умолчанию, чтобы другой программе или пользователю не приходилось вводить все теги вручную, не зная, какое имяэто действительно так.

Заранее спасибо!

Qudeid

Комментарии:

1. Почему вы не можете просто открыть файл .config как XML-документ (с XDocument помощью) и изменить его по мере необходимости?

2. Я могу. Дело не в этом. Я подумал, что может быть более элегантный способ автоматизировать это, без необходимости что-то кодировать. Возможно, я пропустил это или около того. Я полностью могу редактировать файл как XML и даже использовать отражение, чтобы проверить, не хватает ли чего-то. Просто хотел не изобретать велосипед, так сказать.

Ответ №1:

Еще раз привет, ребята,

Я только что создал следующий фрагмент кода, который работает для меня так, как я хотел.

Просто чтобы немного объяснить это: сначала я открываю конфигурационный файл с помощью ConfigurationManager, получаю соответствующий раздел и устанавливаю для ForceSave значение true, чтобы этот раздел обязательно сохранялся. Затем начинается «волшебство». Я перебираю все свойства настроек сборки и позволяю linq творить чудеса, чтобы найти, существует ли элемент. Если нет, я создаю его и добавляю в файл.

Примечание: Этот фрагмент кода предназначен только для настроек приложения, а не для пользовательских настроек, поскольку это другой раздел. Я не пробовал / не тестировал это, но это может быть так же просто, как изменить эту строку:

 ConfigurationSectionGroup sectionGroup = configFile.SectionGroups["applicationSettings"];
  

в эту строку:

 ConfigurationSectionGroup sectionGroup = configFile.SectionGroups["userSettings"];
  

поскольку это соответствующее имя этого раздела. Однако никаких гарантий.

Вот мой код:

 /// <summary>
/// Loads own config file and compares its content to the settings, and adds missing entries with 
/// their default value to the file and saves it.
/// </summary>
private void UpdateSettings()
{
  // Load .config file
  Configuration configFile = ConfigurationManager.OpenExeConfiguration(typeof(Settings).Assembly.Location);

  // Get the wanted section
  ConfigurationSectionGroup sectionGroup = configFile.SectionGroups["applicationSettings"];
  ClientSettingsSection clientSettings = (ClientSettingsSection)sectionGroup.Sections[0];

  // Make sure the section really is saved later on
  clientSettings.SectionInformation.ForceSave = true;

  // Iterate through all properties
  foreach (SettingsProperty property in Settings.Default.Properties)
  {
    // if any element in Settings equals the property's name we know that it exists in the file
    bool exists = clientSettings.Settings.Cast<SettingElement>().Any(element => element.Name == property.Name);

    // Create the SettingElement with the default value if the element happens to be not there.
    if (!exists)
    {
      var element = new SettingElement(property.Name, property.SerializeAs);
      var xElement = new XElement(XName.Get("value"));
      XmlDocument doc = new XmlDocument();
      XmlElement valueXml = doc.ReadNode(xElement.CreateReader()) as XmlElement;
      valueXml.InnerText = property.DefaultValue.ToString();
      element.Value.ValueXml = valueXml;

      clientSettings.Settings.Add(element);
    }
  }

  // Save config
  configFile.Save();
}
  

Ответ №2:

Когда вы создаете параметр в Visual Studio (Project -> Properties -> Settings.settings), вы присваиваете значение этому параметру в редакторе настроек. Из определения настроек (на самом деле это XML-файл) создается файл кода с классом, который предоставляет вам доступ к настройкам. Этот класс будет по умолчанию использовать значение, присвоенное параметру в редакторе настроек. Однако при обращении к параметру он будет искать значение этого параметра в файле App.config. Если есть значение, оно переопределит значение по умолчанию в файле, сгенерированном кодом.

Это означает, что если вы добавляете параметр в свой проект, но не указываете значение для этого параметра в файле App.config, значение параметра будет значением по умолчанию, назначенным в редакторе настроек.

Чтобы переопределить значение, назначьте его в файле App.config для приложения.

Поскольку ваше приложение может быть разделено на несколько сборок, созданных несколькими проектами, невозможно автоматизировать процесс, при котором добавление параметра в зависимую сборку создает запись для этой настройки в файле App.config для основного проекта. Боюсь, вам придется сделать это самостоятельно.

Но в этом и заключается прелесть системы: два EXE-проекта могут зависеть от одного и того же .проект dll, который определяет настройку. В каждом проекте .exe вы можете переопределить настройку в файле App.config для проекта .exe или вы можете использовать значение по умолчанию, определенное в проекте .dll.

Комментарии:

1. Итак, по сути, вы говорите, что app.config — это просто переопределение? Тогда мне пришлось бы, скажем, использовать отражение, чтобы получить все свойства в классе настроек, а затем сравнить его с фактическим файлом. Если чего-то не хватает, запись должна быть добавлена? Я хорошо знаю, что это всего лишь XML-файл, поскольку я настраиваю его в отдельной программе, которая загружает конфигурационный файл другой программы, а затем манипулирует значениями. Но не могу добавить записи, если одна отсутствует.