代码之家  ›  专栏  ›  技术社区  ›  Dave

.net动态刷新app.config

  •  28
  • Dave  · 技术社区  · 17 年前

    如何在.net Windows应用程序中动态重新加载app.config?我需要动态地打开和关闭日志记录,而不仅仅是基于应用程序启动时的值。

    ConfigurationManager.RefreshSection(“appSettings”)不起作用,我还尝试使用OpenExeConfiguration显式打开配置文件,但我总是在应用程序启动时获取缓存值,而不是当前值。

    我已经接受了创建自定义配置部分的答案。作为旁注和愚蠢的错误-如果您是从IDE运行,那么更新app.config文件并期望更改是没有意义的。您必须修改bin\debug文件夹中的.exe.config文件。啊!

    10 回复  |  直到 17 年前
        1
  •  25
  •   Patrick Desjardins    17 年前

    你可以刷新 你自己的 你说的方式是:

    ConfigurationManager.RefreshSection("yoursection/subsection");
    

    只需将日志记录真/假移到一个部分,您就可以了。

        2
  •  7
  •   Mitch Wheat    13 年前

    尽管可以将log4net配置设置添加到项目中 app.config web.config FileSystemWatcher 对象,以便在配置文件更改和动态更新其设置时进行监视。

    要使用单独的配置文件,请将名为Log4Net.config的文件添加到项目中,并将以下属性添加到AssemblyInfo.cs文件中:

    [assembly: log4net.Config.XmlConfigurator(ConfigFile="Log4Net.config", Watch = true)]
    

    注意:对于web应用程序,这假定 Log4Net.config 驻留在web根目录中。确保 log4net.config 文件被标记为复制到输出->总是在属性中复制。

        3
  •  7
  •   Garett    12 年前

    您只需在修改模式下保存配置文件,然后刷新,这将使应用程序从磁盘重新读取该文件。

    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
    
        4
  •  2
  •   foson    16 年前

    请注意,在WinForms中,您可以在应用程序加载之前(之前)对app.config进行编程更改 Application.Start(new Form1()) ),只要你使用 System.Xml 而不是 System.Configuration.ConfigurationManager

    string configFile = Application.ExecutablePath + ".config";  //c:\path\exename.exe.config
    XmlDocument xdoc = new XmlDocument();
    xdoc.Load(configFile);
    XmlNode node = xdoc.SelectSingleNode("/configuration/appSettings/add[@key='nodeToChange']/@value");
    node.Value = "new value";
    File.WriteAllText(setFile, xdoc.InnerXml);
    
        5
  •  1
  •   froeschli    14 年前

    我编写这个实现是为了在运行时更改日志级别,并将新的treshold持久化回app.config(实际上是Application.exe.config)。

    界面:

    internal interface ILoggingConfiguration
    {
      void SetLogLevel(string level);
    
      string GetLogLevel();
    }
    

    实施:

    internal sealed class LoggingConfigurationImpl : ILoggingConfiguration
    {
      #region Members
    
      private static readonly ILog _logger = 
        ObjectManager.Common.Logger.GetLogger();
      private const string DEFAULT_NAME_SPACE = "Default.Name.Space";
    
      #endregion
    
      #region Implementation of ILoggingConfiguration
    
      public void SetLogLevel(string level)
      {
        Level threshold = Log4NetUtils.ConvertToLevel(level);
        ILoggerRepository[] repositories = LogManager.GetAllRepositories();
    
        foreach (ILoggerRepository repository in repositories)
        {
          try
          {
            SetLogLevelOnRepository(repository, threshold);
          }
          catch (Exception ex)
          {
            _logger.ErrorFormat("Exception while changing log-level: {0}", ex);
          }
        }
        PersistLogLevel(level);
      }
    
      public string GetLogLevel()
      {
        ILoggerRepository repository = LogManager.GetRepository();
        Hierarchy hierarchy = (Hierarchy) repository;
        ILogger logger = hierarchy.GetLogger(DEFAULT_NAME_SPACE);
        return ((Logger) logger).Level.DisplayName;
      }
    
      private void SetLogLevelOnRepository(ILoggerRepository repository,
                                           Level threshold)
      {
        repository.Threshold = threshold;
        Hierarchy hierarchy = (Hierarchy)repository;
        ILogger[] loggers = hierarchy.GetCurrentLoggers();
        foreach (ILogger logger in loggers)
        {
          try
          {
            SetLogLevelOnLogger(threshold, logger);
          }
          catch (Exception ex)
          {
            _logger.ErrorFormat("Exception while changing log-level for 
                logger: {0}{1}{2}", logger, Environment.NewLine, ex);
          }
        }
      }
    
      private void SetLogLevelOnLogger(Level threshold, ILogger logger)
      {
        ((Logger)logger).Level = threshold;
      }
    
      private void PersistLogLevel(string level)
      {
        XmlDocument config = new XmlDocument();
        config.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
        string xpath =
          String.Format("configuration/log4net/logger[@name='{0}']/level",
            DEFAULT_NAME_SPACE);
        XmlNode rootLoggerNode = config.SelectSingleNode(xpath);
    
        try
        {
          rootLoggerNode.Attributes["value"].Value = level;
          config.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
    
          ConfigurationManager.RefreshSection("log4net");
        }
        catch(Exception ex)
        {
          _logger.ErrorFormat("error while persisting new log-level: {0}", ex);
        }
      }
    
      #endregion
    }
    

    帮助器类Log4NetUtils:

    public sealed class Log4NetUtils
    {
      private static readonly ILoggerRepository _loggerRepository =
         LoggerManager.GetAllRepositories().First();
    
      public static Level ConvertToLevel(string level)
      {
        return _loggerRepository.LevelMap[level];
      }
    }
    

    XAML代码:

    <ComboBox Name="cbxLogLevel" Text="{Binding LogLevel}">
      <ComboBoxItem Content="DEBUG" />
      <ComboBoxItem Content="INFO" />
      <ComboBoxItem Content="WARN" />
      <ComboBoxItem Content="ERROR" />
    </ComboBox>
    <Button Name="btnChangeLogLevel" 
            Command="{Binding SetLogLevelCommand}"
            CommandParameter="{Binding ElementName=cbxLogLevel, Path=Text}" >
                Change log level
    </Button>
    
        6
  •  0
  •   MusiGenesis    17 年前

    我认为没有任何方法可以做到这一点,除非您使用XML编写自己的配置文件读取器。为什么不在应用程序开始时根据配置文件设置打开或关闭日志记录,然后在程序运行时动态打开或关闭它呢?

        7
  •  0
  •   Tigraine    17 年前

    我想我在log4net文档中读到这是不可能的。

    http://logging.apache.org/log4net/release/manual/configuration.html#.config%20Files

    无法在运行时重新加载app.config。

        8
  •  0
  •   eduesing    17 年前

    我建议使用另一个XML文件,而不是app.config。您甚至可以监视文件的更改,并在更改时自动重新加载它。

        9
  •  0
  •   jorge E P jorge E P    16 年前

    实际使用:

    Application.restart();

    对我来说效果不错。

    当做

    乔治

        10
  •  0
  •   Zugbo Sudhanshu Mishra    13 年前

    我已尝试使用RefreshSection方法,并使用以下代码示例使其正常工作:

    class Program
        {
            static void Main(string[] args)
            {
                string value = string.Empty, key = "mySetting";
                Program program = new Program();
    
                program.GetValue(program, key);
                Console.WriteLine("--------------------------------------------------------------");
                Console.WriteLine("Press any key to exit...");
                Console.ReadLine();
            }
    
            /// <summary>
            /// Gets the value of the specified key from app.config file.
            /// </summary>
            /// <param name="program">The instance of the program.</param>
            /// <param name="key">The key.</param>
            private void GetValue(Program program, string key)
            {
                string value;
                if (ConfigurationManager.AppSettings.AllKeys.Contains(key))
                {
                    Console.WriteLine("--------------------------------------------------------------");
                    Console.WriteLine("Key found, evaluating value...");
                    value = ConfigurationManager.AppSettings[key];
                    Console.WriteLine("Value read from app.confg for Key = {0} is {1}", key, value);
                    Console.WriteLine("--------------------------------------------------------------");
    
                    //// Update the value
                    program.UpdateAppSettings(key, "newValue");
                    //// Re-read from config file
                    value = ConfigurationManager.AppSettings[key];
                    Console.WriteLine("New Value read from app.confg for Key = {0} is {1}", key, value);
                }
                else
                {
                    Console.WriteLine("Specified key not found in app.config");
                }
            }
    
            /// <summary>
            /// Updates the app settings.
            /// </summary>
            /// <param name="key">The key.</param>
            /// <param name="value">The value.</param>
            public void UpdateAppSettings(string key, string value)
            {
                Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    
                if (configuration.AppSettings.Settings.AllKeys.Contains(key))
                {
                    configuration.AppSettings.Settings[key].Value = value;
                }
    
                configuration.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
            }
    
    推荐文章