【问题标题】:c# forms - Programatically add missing entrys in .config filec# forms - 以编程方式在 .config 文件中添加缺少的条目
【发布时间】:2011-11-30 17:47:52
【问题描述】:

一个问题我在谷歌上搜索了很长一段时间后都没有找到答案(然后长时间中断并再次搜索)......

假设,我的应用程序设置中有 2 个设置。字符串 1 和字符串 2。进一步说,我们发布了产品并开始添加次要功能(更多需要配置的东西),我们添加了一个 String3。 如何在不手动遍历 .config 文件的情况下添加缺失的条目?当作为更新发布时(不带 OneClick 顺便说一句。)现有的 .config 文件只有 String1 和 String2。

虽然默认为 String3,但应用程序以某种方式理解缺少一个条目,因此应该有可能,或者我认为,使用默认值添加这个设置,以便另一个程序或用户不会'不必手动输入整个标签,而不知道它到底是什么名字。

提前致谢!

奎迪德

【问题讨论】:

  • 为什么不能像 XML 文档一样打开 .config 文件(带有XDocument)并根据需要进行修改?
  • 我可以。那不是重点。我认为可能有一种更优雅的方式可以实现自动化,而无需编写代码。也许我错过了它,或者如此。我完全可以将文件编辑为 XML,甚至可以使用反射来检查是否缺少某些内容。只是不想重新发明轮子,可以这么说。

标签: c# forms settings app-config


【解决方案1】:

在 Visual Studio(项目 -> 属性 -> Settings.settings)中创建设置时,您在设置编辑器中为该设置分配一个值。从设置定义(实际上是一个 XML 文件)生成一个代码文件,其中包含一个允许您访问设置的类。此类将默认使用在设置编辑器中分配给设置的值。但是,当访问该设置时,它将在 App.config 文件中查找该设置的值。如果有值,它将覆盖代码生成文件中的默认值。

这意味着,如果您向项目添加设置但未在 App.config 文件中为该设置提供值,则该设置的值将是设置编辑器中分配的默认值。

要覆盖在应用程序的 App.config 文件中分配的值。

由于您的应用程序可以拆分为由多个项目创建的多个程序集,因此无法自动执行在依赖程序集中添加设置的过程会为该设置为主项目的 App.config 文件创建一个条目。恐怕你必须自己做。

但这正是系统的美妙之处:两个 .exe 项目可以依赖于定义设置的同一个 .dll 项目。在每个 .exe 项目中,您可以覆盖 .exe 项目的 App.config 文件中的设置,或者您可以决定使用 .dll 项目定义的默认值。

【讨论】:

  • 所以,基本上,您是说 app.config 只是一个覆盖?然后,我将不得不使用反射来获取 Settings 类中的所有属性,然后将其与实际文件进行比较。如果缺少某些内容,是否应该添加条目?我很清楚这只是一个 XML 文件,因为我在一个单独的程序中配置它,它加载另一个程序的配置文件,然后操作这些值。但如果缺少条目,则无法添加条目。
【解决方案2】:

大家好,

我刚刚编写了以下代码,它可以满足我的需要。

稍微解释一下: 我首先使用 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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多