2008-11-07 25 views
28

¿Cómo recargo dinámicamente el app.config en una aplicación de Windows .net? Necesito activar y desactivar el inicio de sesión de forma dinámica y no solo en función del valor al inicio de la aplicación..net actualizar dinámicamente app.config

ConfigurationManager.RefreshSection ("appSettings") no funciona y también he intentado abrir explícitamente el archivo de configuración utilizando OpenExeConfiguration, pero siempre obtengo el valor en caché al inicio de la aplicación y no el valor actual.

He aceptado la respuesta de crear una sección de configuración personalizada. Como nota al margen y error tonto: si está ejecutando desde el IDE, no tiene sentido actualizar el archivo app.config y esperar cambios. Debe modificar el archivo .exe.config en la carpeta bin \ debug. Doh!

+1

El uso de .NET 4.0 y VS2013update4 esto funciona bien para mí. es decir, solo estoy llamando a ConfigurationManager.RefreshSection ("appSettings") después de haber modificado el archivo app.config en el disco y vuelve a cargar las configuraciones correctamente. –

+0

Falta un pequeño detalle: después de hacer lo de ConfigurationManager.RefreshSection ("appSettings"), tiene que volver a cargar la configuración = ConfigurationManager.OpenExeConfiguration (Application.ExecutablePath) –

Respuesta

24

se puede refrescar su propia sección la forma en que dicen:

ConfigurationManager.RefreshSection("yoursection/subsection"); 

Basta con mover un registro de verdadero/falso en una sección y se le multa.

0

No creo que haya ninguna forma de hacerlo, a menos que escriba su propio lector de archivos de configuración usando XML. ¿Por qué no activar o desactivar el inicio de sesión al inicio de la aplicación según la configuración del archivo de configuración y luego activarlo o desactivarlo de forma dinámica mientras se ejecuta el programa?

0

Creo que he leído en la documentación de log4net que esto no es posible.

trate de hacer que el registro en un archivo de registro externa que puede ser visto con una FileSystemWatcher

Actualización: Se encontraron de nuevo .. http://logging.apache.org/log4net/release/manual/configuration.html#.config%20Files

No hay manera de recargar la app.config en tiempo de ejecución.

+0

log4net no permite activar o desactivar el registro de forma dinámica? – MusiGenesis

+0

Log4net permite esto. Pero si su configuración de log4net está configurada en su application.config, entonces no hay forma de cambiar esa configuración durante el tiempo de ejecución. – Tigraine

0

Recomendaría usar otro archivo XML y no app.config. Incluso podría ver el archivo en busca de cambios y volver a cargarlo automáticamente cuando cambie.

7

Si está utilizando Log4net, puede hacer lo que le pide:

Aunque es posible añadir los valores de configuración log4net a app.config o web.config de archivos de su proyecto, es preferible colocarlos en un archivo de configuración independiente . Además del beneficio obvio de la facilidad de mantenimiento, tiene el beneficio adicional de que log4net puede colocar un objeto FileSystemWatcher en su archivo de configuración para monitorear cuándo cambia y actualizar su configuración de forma dinámica.

Para utilizar un archivo de configuración distinto, añadir un archivo llamado log4net.config a su proyecto y agregue el atributo siguiente a su archivo AssemblyInfo.cs:

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

Nota: para aplicaciones web, esto supone que reside Log4Net.config en la raíz web. Asegúrese de que el archivo log4net.config esté marcado como "Copiar a la salida" -> "Copiar siempre" en Propiedades.

2

Solo una nota, en WinForms, puede realizar cambios programáticos en su aplicación.config antes de que sus cargas de aplicación (antes Application.Start(new Form1())), siempre y cuando se utiliza en lugar de System.XmlSystem.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); 
0

usando una realidad:

Application.restart();

Me ha funcionado bastante bien.

Saludos

Jorge

+0

Application.restart() no funcionará si tiene variables que necesitan conservar su estado. Además, terminé generando una nueva ventana con un retraso de alrededor de 10-15 segundos para cerrar la anterior, por lo que esta no es la solución ideal. –

7

A continuación se presenta el truco que se puede poner esto hará que config para leer del disco.

Solo necesita guardar el archivo de configuración en modo modificado y luego actualizar esto hará que la aplicación lea el archivo desde el disco.

ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).Save(ConfigurationSaveMode.Modified); 
      ConfigurationManager.RefreshSection("appSettings"); 
+0

¿Alguien más ha intentado esto? –

+0

@DanielAllenLangdon: (Última respuesta, lo sé) Intenté llamar al método Guardar con el parámetro sugerido y funciona – dotnetguy

+0

He agregado el código que utilicé como respuesta. solo en caso de que alguien quiera echarle un vistazo – dotnetguy

1

Escribí esta aplicación para cambiar el nivel de registro en tiempo de ejecución y persistir el nuevo umbral de vuelta a la app.config (en realidad el Application.exe.config).

la interfaz:

internal interface ILoggingConfiguration 
{ 
    void SetLogLevel(string level); 

    string GetLogLevel(); 
} 

La aplicación:

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 
} 

Los Log4NetUtils clase de ayuda:

public sealed class Log4NetUtils 
{ 
    private static readonly ILoggerRepository _loggerRepository = 
    LoggerManager.GetAllRepositories().First(); 

    public static Level ConvertToLevel(string level) 
    { 
    return _loggerRepository.LevelMap[level]; 
    } 
} 

El código 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> 
0

He intentado usar el método RefreshSection y tengo que trabajar con el siguiente ejemplo de código:

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"); 
     } 
Cuestiones relacionadas