.net dynamically refresh app.config

前端 未结 10 757
闹比i
闹比i 2020-12-02 23:28

How do I dynamically reload the app.config in a .net Windows application? I need to turn logging on and off dynamically and not just based upon the value at application sta

相关标签:
10条回答
  • 2020-12-02 23:51

    Following is the hack which you can put this will make config to read from disk.

    You just need to save the config file in Modified Mode and then refresh this will make application to read the file agian from the disk.

    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
    
    0 讨论(0)
  • 2020-12-02 23:52

    I wrote this implementation to change the log level at runtime and persist the new treshold back to the app.config (actually the Application.exe.config).

    The interface:

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

    The implementation:

    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
    }
    

    The helper class Log4NetUtils:

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

    The XAML code:

    <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>
    
    0 讨论(0)
  • 2020-12-02 23:57

    Actually using an:

    Application.restart();

    Has worked pretty good for me.

    Regards

    Jorge

    0 讨论(0)
  • 2020-12-02 23:58

    I think I read in the log4net documentation that this is not possible.

    Try having the logging in an external logfile that can be watched with a filesystemwatcher

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

    There is no way to reload the app.config during runtime.

    0 讨论(0)
提交回复
热议问题