8

Estoy escribiendo una aplicación de prueba WinForms/C#/.NET 3.5 para el sistema que estamos desarrollando y nos cayó la necesidad de cambiar entre archivos .config en tiempo de ejecución, pero esto está resultando ser una pesadillaCambiando App.config en Runtime

Aquí está la escena: la aplicación WinForms está destinada a probar una aplicación web, dividida en 5 subsistemas. El proceso de prueba funciona con mensajes que se envían entre los subsistemas, y para que este proceso sea exitoso, cada subsistema tiene su propio archivo .config.

Para mi solicitud de prueba escribí 5 archivos de configuración separados. Me gustaría poder cambiar entre estos 5 archivos durante el tiempo de ejecución, pero el problema es: puedo editar programáticamente el archivo .config de la aplicación varias veces, pero estos cambios solo tendrán efecto una vez. He estado buscando un formulario para resolver este problema durante mucho tiempo, pero aún así no tuve éxito.

Sé que la definición del problema puede ser un poco confusa, pero realmente agradecería que alguien me ayudara.

¡Gracias de antemano!

--- --- ACTUALIZACIÓN 01-06-10

Hay algo que no he mencionado antes. Originalmente, nuestro sistema es una aplicación web con llamadas WCF entre cada subsistema. Por motivos de prueba de rendimiento (estamos utilizando ANTS 4), tuvimos que crear una copia local de los ensamblajes y hacer referencia a ellos desde el proyecto de prueba. Puede sonar un poco incorrecto, pero no pudimos encontrar una forma satisfactoria de medir el rendimiento de una aplicación remota.

actualización

--- --- Fin

Esto es lo que estoy haciendo:

public void UpdateAppSettings(string key, string value) 
{ 
    XmlDocument xmlDoc = XmlDocument.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

    foreach (XmlElement item in xmlDoc.DocumentElement) 
    { 
     foreach (XmlNode node in item.ChildNodes) 
     { 
      if (node.Name == key) 
      { 
       node.Attributes[0].Value = value; 
       break; 
      } 
     } 
    } 

    xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 

    System.Configuration.ConfigurationManager.RefreshSection("section/subSection");  
} 
+0

dup/related? http://stackoverflow.com/questions/1542171/change-app-config-at-runtime – Hogan

+0

Ya he probado estos enfoques ... el problema es que la etiqueta que estoy cambiando está fuera de . También intenté crear nuevos AppDomains y establecer diferentes archivos .config para ellos, pero tampoco funcionó. –

Respuesta

3

ACTUALIZACIÓN

La solución abajo no funciona porque no dispone XmlDocument y parece que algunas versiones de .NET no cierre correctamente cuando se les una ruta de archivo. La solución (código de ejemplo en el enlace) es abrir una secuencia que hará un desecho y pasará esa secuencia a la función de guardar.

Aquí se muestra una solución.http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Cosas viejas continuación

Prueba esto:

Nota, me cambió a XPath, pero ha sido un tiempo por lo que podría haber conseguido el XPath mal, pero en cualquier caso deberías usar xpath y no caminar por el árbol. Como pueden ver, es mucho más claro.

El punto importante es la declaración using que será dispose(), que creo que fue su problema.

Avísame, buena suerte.

public void UpdateAppSettings(string key, string value) 
    { 
    using (XmlDocument xmlDoc = new XmlDocument()) 
    { 
     xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 
     xmlDoc.DocumentElement.FirstChild.SelectSingleNode("descendant::"+key).Attributes[0].Value = value; 
     xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile); 
    } 
    System.Configuration.ConfigurationManager.RefreshSection("section/subSection"); 
    } 
+1

Eso tiene sentido, el problema es que XmlDocument no implementa IDisposable, por lo que no es posible utilizar el ámbito "usar". –

+0

Sí, tienes razón ... mira mis comentarios arriba. – Hogan

+0

Bueno, tengo una ligera suposición de que este no es el caso. Estoy usando framework .NET 3.5. Además, creo que si la secuencia de archivos aún estuviera abierta, por segunda vez intentaría escribir en el archivo xml, obtendría una excepción ... pero gracias de todos modos. –

2

Mi conjetura es que no son realmente de cerrar el archivo manejar la primera vez que las ventanillas no "ve "Estás haciendo los cambios posteriores.

Mis sugerencias son utilizar una llamada API a IIS y apagar la aplicación web (y el grupo), realizar el cambio, activar la aplicación web. De esta forma, está seguro de que volverá a leer el archivo y tendrá un entorno "limpio" para cada prueba.

+0

Actualicé la pregunta con algunos detalles. Básicamente, en este contexto (pruebas de rendimiento) no estamos utilizando IIS, los ensamblados se referencian localmente. Estoy usando bibliotecas Xml para escribir en el archivo .config. Durante la ejecución, puedo ver que el archivo se está escribiendo y modificando. –

1

Suponiendo que el identificador de archivo del archivo de configuración se cierra después de que se haya leído y procesado el archivo de configuración, enviaría un mensaje a la aplicación para indicarle que vuelva a leer el archivo de configuración después de haberlo actualizado. Si este enfoque no funciona, entonces sospecho (como sugirió Hogan) que el identificador del archivo no está cerrado. ¿Qué códigos de error obtiene al abrir el archivo, leer y cerrar las llamadas al sistema? (perror utilizar para informar del mensaje de error)

+1

Este enfoque es interesante, pero ¿me puede dar algunos pasos sobre cómo enviar este mensaje a la aplicación? Intenté llamar a ConfigurationManager.RefreshSection() pero no funcionó. –

+1

@born to hula: ¿Cómo se cambia la configuración @ runtime? Utilizaría el mismo enfoque para que la aplicación vuelva a leer el archivo de configuración. ¿Qué lenguaje y SO estás usando? ¿Cuáles son los mensajes enviados a la aplicación durante la prueba? ¿La entrada a la aplicación proviene de una página web? Responder estas preguntas daría algunas pistas sobre el mejor enfoque para su situación. –

+0

Estoy usando XmlDocument para cambiar el archivo .config (consulte la pregunta actualizada). Pero, independientemente de cuántas veces lo cambie, los cambios solo se reflejarán una vez en el contexto de ejecución. Estoy usando C# y Windows XP. La entrada de la aplicación proviene directamente del formulario. Básicamente, la entrada principal es un mensaje, a partir del cual se crea una variedad de objetos. –

24

Entiendo que este es un hilo bastante antiguo, pero no pude conseguir que los métodos enumerados funcionaran. Aquí es una versión más sencilla del método UpdateAppSettings (utilizando .NET 4.0):

private void UpdateAppSettings(string theKey, string theValue) 
     { 
      Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
      if (ConfigurationManager.AppSettings.AllKeys.Contains(theKey)) 
      { 
       configuration.AppSettings.Settings[theKey].Value = theValue; 
      } 

      configuration.Save(ConfigurationSaveMode.Modified); 

      ConfigurationManager.RefreshSection("appSettings"); 
     } 

Bastante fácil de leer y evita tener que atravesar el app.config usar Xpath o similares. Nota: El código anterior está inspirado en el fragmento this en MSDN.