2

Я хочу использовать пользовательский путь для файла user.config, а не читать .NET из местоположения по умолчанию.Чтение и запись значений в файлах .NET .config

Я открываю файл, как это:

ExeConfigurationFileMap configMap = new ExeConfigurationFileMap(); 
configMap.ExeConfigFilename = String.Format("{0}\\user.config",AppDataPath); 
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.PerUserRoamingAndLocal); 

Но я не могу понять, как на самом деле читать настройки из этого, я получаю ошибку компиляции говорят, что значения недоступны, когда я пытаюсь получить значение через AppData или ConfigurationSection.

Должен ли я создать какой-либо класс-оболочку для правильного использования данных?

+0

У вас есть разделы пользовательских настроек? Как выглядит файл конфигурации и как выглядит ваш потребительский код? – yamen

+0

@yamen нет, в основном наличие. – Brian

ответ

2

Мне недавно была задана аналогичная проблема, мне пришлось изменить местоположение файлов настроек, которые были прочитаны из местоположения по умолчанию в AppData, в каталог приложения. Мое решение состояло в том, чтобы создать свои собственные файлы настроек, полученные из ApplicationSettingsBase, которые указали пользовательский номер SettingsProvider. Несмотря на то, что решение сначала казалось излишним, я нашел его более гибким и удобным, чем я ожидал.

Update:

Пример настройки файла:

public class BaseSettings : ApplicationSettingsBase 
{ 
    protected BaseSettings(string settingsKey) 
     { SettingsKey = settingsKey.ToLower(); } 


    public override void Upgrade() 
    { 
     if (!UpgradeRequired) 
      return; 
     base.Upgrade(); 
     UpgradeRequired = false; 
     Save(); 
    } 


    [SettingsProvider(typeof(MySettingsProvider)), UserScopedSetting] 
    [DefaultSettingValue("True")] 
    public bool UpgradeRequired 
    { 
     get { return (bool)this["UpgradeRequired"]; } 
     set { this["UpgradeRequired"] = value; } 
    } 
} 

Образец SettingsProvider:

public sealed class MySettingsProvider : SettingsProvider 
{ 
    public override string ApplicationName { get { return Application.ProductName; } set { } } 
    public override string Name { get { return "MySettingsProvider"; } } 


    public override void Initialize(string name, NameValueCollection col) 
     { base.Initialize(ApplicationName, col); } 


    public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propertyValues) 
    { 
     // Use an XmlWriter to write settings to file. Iterate PropertyValueCollection and use the SerializedValue member 
    } 


    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props) 
    { 
     // Read values from settings file into a PropertyValuesCollection and return it 
    } 


    static MySettingsProvider() 
    { 
     appSettingsPath_ = Path.Combine(new FileInfo(Application.ExecutablePath).DirectoryName, settingsFileName_); 

     settingsXml_ = new XmlDocument(); 
     try { settingsXml_.Load(appSettingsPath_); } 
     catch (XmlException) { CreateXmlFile_(settingsXml_); } //Invalid settings file 
     catch (FileNotFoundException) { CreateXmlFile_(settingsXml_); } // Missing settings file 
    } 
} 
+0

В конце концов, я закончил делать что-то очень похожее. Кажется, должно быть проще получить работу Конфигурации, но мои потребности в этом были настолько простыми, что просто не оправдывали траты больше времени на проблему. – Brian

1

Несколько улучшений:

1) Загрузите это немного проще, нет необходимости в других линиях:

var config = ConfigurationManager.OpenExeConfiguration(...); 

2) Доступ AppSettings правильно:

config.AppSettings.Settings[...]; // and other things under AppSettings 

3) Если вы хотите создать пользовательскую конфигурацию, используйте этот инструмент: http://csd.codeplex.com/

0

Я никогда не в конечном итоге получить подход Configuration Manager работает. Проведя полдня, путаясь без каких-либо успехов, я решил опрокинуть свое решение, так как мои основные потребности.

Вот решение, которое я придумал в конце концов:

public class Settings 
{ 
    private XmlDocument _xmlDoc; 
    private XmlNode _settingsNode; 
    private string _path; 

    public Settings(string path) 
    { 
     _path = path; 
     LoadConfig(path); 
    } 

    private void LoadConfig(string path) 
    { 
     //TODO: add error handling 
     _xmlDoc = null; 
     _xmlDoc = new XmlDocument(); 
     _xmlDoc.Load(path); 
     _settingsNode = _xmlDoc.SelectSingleNode("//appSettings"); 
    } 

    // 
    //use the same structure as in .config appSettings sections 
    // 
    public string this[string s] 
    { 
     get 
     { 
      XmlNode n = _settingsNode.SelectSingleNode(String.Format("//add[@key='{0}']", s)); 
      return n != null ? n.Attributes["value"].Value : null; 
     } 
     set 
     { 
      XmlNode n = _settingsNode.SelectSingleNode(String.Format("//add[@key='{0}']", s)); 

      //create the node if it doesn't exist 
      if (n == null) 
      { 
       n=_xmlDoc.CreateElement("add"); 
       _settingsNode.AppendChild(n); 
       XmlAttribute attr =_xmlDoc.CreateAttribute("key"); 
       attr.Value = s; 
       n.Attributes.Append(attr); 
       attr = _xmlDoc.CreateAttribute("value"); 
       n.Attributes.Append(attr); 
      } 

      n.Attributes["value"].Value = value; 
      _xmlDoc.Save(_path); 
     } 
    } 
}