2010-03-05 26 views
9

Existen preguntas relacionadas con reading settings from a separate config file y otras similares, pero mi pregunta es específica de la configuración de la propiedad de la aplicación (es decir, <MyApplication.Properties.Settings> - vea el archivo XML a continuación) y cómo cargarlos dinámicamente. He probado el método en el this post, que involucró a la actualización de la sección completa appSettings del archivo de configuración principal, pero mi adaptación tiró excepciones porque no estaba reemplazando la sección appsettings:¿Cómo cargar un archivo de configuración de la aplicación por separado de forma dinámica y combinar con la configuración actual?

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); 
// Have tried the other ConfigurationUserLevels to no avail 
config.AppSettings.File = myRuntimeConfigFilePath; 
config.Save(ConfigurationSaveMode.Modified); // throws ConfigurationErrorsException 
ConfigurationManager.RefreshSection("userSettings"); 

El ConfigurationErrorsException.Message es "La raíz el elemento debe coincidir con el nombre de la sección que hace referencia al archivo, 'appSettings' (C: \ myFile.xml línea 2). " El archivo es:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <userSettings> 
     <MyApplication.Properties.Settings> 
      <setting name="SineWaveFrequency" serializeAs="String"> 
       <value>6</value> 
      </setting> 
      <setting name="SineWaveAmplitude" serializeAs="String"> 
       <value>6</value> 
      </setting> 
     </MyApplication.Properties.Settings> 
    </userSettings> 
</configuration> 

¿Hay una manera de importar los valores de este archivo en la clase MyApplication.Properties.Settings.Default, con el manejo de toda la deserialización XML como lo hace cuando el archivo de configuración se carga al iniciar la aplicación marco?

+0

En caso de que sienta curiosidad por la motivación, consulte mi pregunta anterior: [Cómo usar los archivos de configuración .NET (app.config, settings.settings) para guardar y restaurar todos los datos de la aplicación?] (Http: // stackoverflow. com/questions/1869628/how-to-use-net-configuration-files-app-config-settings-to-save-and-r). En ese momento, no sabía la diferencia entre app.config y user.config, pero definitivamente estoy buscando una solución para modificar user.config. – Pat

Respuesta

7

Bueno, esto funciona:

using System; 
using System.Configuration; 
using System.IO; 
using System.Linq; 
using System.Xml.Linq; 
using System.Xml.XPath; 

public static class SettingsIO 
{ 
    internal static void Import(string settingsFilePath) 
    { 
     if (!File.Exists(settingsFilePath)) 
     { 
      throw new FileNotFoundException(); 
     } 

     var appSettings = Properties.Settings.Default; 
     try 
     { 
      var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal); 

      string appSettingsXmlName = 
Properties.Settings.Default.Context["GroupName"].ToString(); 
// returns "MyApplication.Properties.Settings"; 

      // Open settings file as XML 
      var import = XDocument.Load(settingsFilePath); 
      // Get the whole XML inside the settings node 
      var settings = import.XPathSelectElements("//" + appSettingsXmlName); 

      config.GetSectionGroup("userSettings") 
       .Sections[appSettingsXmlName] 
       .SectionInformation 
       .SetRawXml(settings.Single().ToString()); 
      config.Save(ConfigurationSaveMode.Modified); 
      ConfigurationManager.RefreshSection("userSettings"); 

      appSettings.Reload(); 
     } 
     catch (Exception) // Should make this more specific 
     { 
      // Could not import settings. 
      appSettings.Reload(); // from last set saved, not defaults 
     } 
    } 

    internal static void Export(string settingsFilePath) 
    { 
     Properties.Settings.Default.Save(); 
     var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal); 
     config.SaveAs(settingsFilePath); 
    } 
} 

El método de exportación crea un archivo como el siguiente:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <userSettings> 
     <MyApplication.Properties.Settings> 
      <setting name="SineWaveFrequency" serializeAs="String"> 
       <value>1</value> 
      </setting> 
      <setting name="SineWaveAmplitude" serializeAs="String"> 
       <value>100</value> 
      </setting> 
      <setting name="AdcShift" serializeAs="String"> 
       <value>8</value> 
      </setting> 
      <setting name="ControlBitsCheckedIndices" serializeAs="String"> 
       <value>0,1,2,3,5,6,7,8</value> 
      </setting> 
      <setting name="UpgradeSettings" serializeAs="String"> 
       <value>False</value> 
      </setting> 
     </MyApplication.Properties.Settings> 
    </userSettings> 
</configuration> 

El método de importación descompone el archivo, toma el todo dentro del nodo, pone que XML en el archivo user.config en la sección correspondiente, luego vuelve a cargar Properties.Settings.Default para obtener esos valores del nuevo archivo user.config.

+0

Tenga en cuenta que debe agregar una referencia al ensamblado System.Configuration. – Pat

0

La solución sugerida por Pat:

// Get the whole XML inside the settings node 
var settings = import.XPathSelectElements("//" + appSettingsXmlName); 

rendimientos null. Lo cambié a

var settings = import.Element("configuration").Element("userSettings").Element(appSettingsXmlName); 

config.GetSectionGroup("userSettings") 
     .Sections[appSettingsXmlName] 
     .SectionInformation 
     .SetRawXml(settings.ToString()); 

Y funciona perfectamente.

Cuestiones relacionadas