2009-12-08 26 views
6

.net yapılandırma dosyaları hakkında pek çok yayın olmasına rağmen, gereksinimlerimin önerilen çözümlerden herhangi birine izin vermediğine inanıyorum (veya bu işlemi benim için çalışmasını sağlayacak kadar anlamıyorum).Tüm uygulama verilerini kaydetmek ve geri yüklemek için .NET yapılandırma dosyaları (app.config, settings.settings) nasıl kullanılır?

durum bir Windows belirli kullanıcı giriş alanları (örneğin IP Adresi), hem de uygulama ayarlarına form özelliklerini (pencere boyutu, vs) bağlanan bir uygulama (sadece de başka bir uygulamayı olabilir) (Forms olması Özellikler-> Ayarlar alanında). Anladığım kadarıyla, bu ayarlar projemin app.config dosyasında gösterilenlerle aynıdır, bu yüzden bu ayarları değiştirmek için System.Configuration.ConfigurationManager sınıfını kullanabilmem gerekir.

Yapmak istediğim, kullanıcının kayıtlı tüm ayarları almasına ve içe aktarmasına izin vermektir. Bazı özel nesnelerin serileştirilmesini yapmak veya INI dosyaları ile çalışmak yerine, uygulamanın kullandığı yapılandırma dosyasını kaydetmenin ve değiştirmenin daha kolay olacağını düşündüm.

Bir belirtilen dosyaya geçerli ayarları kaydetmek için nispeten kolaydır: Mevcut ayarları üzerine yazmak bir yapılandırma dosyasını geri

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

, zor kanıtlıyor. Öyle

var newConfig = ConfigurationManager.OpenExeConfiguration(settingsFilePath) 

gibi bir yapılandırma dosyasını açabilirsiniz ama tamamen ithal dosyanın olanlarla şimdiki config tüm ayarları nasıl değiştirileceği görmüyorum gibi görünüyor. [Düzenle: Bu aşırı yükleme .exe dosyasının değil .config dosyasının yolunu almalıdır. Bir exe dosyasını bu şekilde açmak, çağıran kod yapılandırma dosyasında aynı derlemeleri referans göstermiyorsa ConfigurationErrorsException atar.]

Belki de yalnızca bir bölümünün yerine geçmek için other posts numaralı belgede belirtilen yöntemleri kullanmam gerekiyor config, ve her şeyi değil, ama bu noktada bunun nasıl olacağını görmüyorum.

Herhangi bir fikrin var mı? Doğru parçayı mı indiriyorum yoksa sadece INI dosyalarını mı kullanmalıyım?

cevap

1

Tüm yapılandırma dosyasını geçersiz kılmanın iyi bir fikir olduğunu düşünmüyorum. Bu dosyadaki ayarların bir kısmı, gerçekten herhangi bir kodunuzun .NET CLR'nin başlatılmasıyla ilgili olan herhangi bir şeyi yapma şansına sahip olmasından önce, gerçekten erken işlenecek ayarlar içerebilir.

+0

Dosyanın tamamını işlemek konusunda haklısınız gibi görünüyorsunuz: Bellekte, en azından, ilgilendiğimi düşündüğüm "appSettings" den daha fazla bölüm var. Ne demek istediğimi görmek için, var currentConfig = ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.PerUserRoamingAndLocal) öğesini deneyin; currentConfig.Dump(); LINQPad'de . – Pat

+0

Değiştirmek istediğim "appSettings" değeri değil, "userSettings" değeri olduğunu keşfettim. Özellikle, bu numaralı düğümdür. – Pat

3

Eğer dosya bir XDocument içine yüklemek basit bir xml dosyasıdır App.Config beri:


string path = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 
XDocument doc = XDocument.Load(path); 
//Do your modifications to section x 
doc.Save(path); 
ConfigurationManager.RefreshSection("x"); 
Ben Pat'in comment

+0

Öneri için teşekkürler, ancak belirlediğiniz yol kullanıcı ayarlarını değiştirmek için doğru olanı değil. Ayrıca, başka birinin bunu denemek istemesi durumunda, Load, XDocument sınıfının statik bir yöntemidir, bu nedenle sözdizimi, var doc = XDocument.Load (yol); şeklindedir. Bu yöntemin işe yarayıp yaramadığını görmek için XML dosyasının bölümlerini okumaya ve değiştirmeye devam edeceğim, ancak henüz şansınız yok. – Pat

+0

Yol, işlemek istediğiniz bölümün nerede olduğunu düşündüğüm App.config öğesinin üzerine gelmelidir. – Manu

3
@ göre XDocument.Load() kodunu düzeltilmiş

App.config dosyasına yazmamak, ancak değiştirilen kullanıcı ayarlarını kaydetmek için ayarlar dosyasını kullanmak en iyi uygulamadır. App.config ve web.config sadece salt okunur değerler için kullanılmalıdır.

+0

Tamam, ama bu nasıl yapılır? Ben zaten uygulama çalışır arasında kullanıcı girişi devam etmek için ayarlar dosyasını kullanıyorum, ama bu bilgileri ayrı bir dosya (ithalat/ihracat) olarak nasıl kaydedip geri yükleyebilirim? – Pat

+0

Manu'dan aşağıdaki yazı olarak, sadece bir XML dosyası olarak düşünün. – Kenoyer130

+0

Yine, bu nasıl yapılır? Benim anlayışım, "dosya" ayarlarının gerçekten sadece app.config olduğunu, ayarların nerede saklandığını görmektir. Açıklamalar? – Pat

0

Manu'nun dosyayı sadece XML olarak okuyabilme önerisi sayesinde, this solution'u birlikte okudum. (Yalnızca bir TextBox'un Text özelliği gibi dizeler olarak kaydedilen özellikler için geçerli biçimde çalışır. Örneğin, NumericUpDown denetiminin Value özelliğini sürdürürseniz işe yaramaz.

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <userSettings> 
     <HawkConfigGUI.Properties.Settings> 
      <setting name="FpgaFilePath" serializeAs="String"> 
       <value>testfpga</value> 
      </setting> 
      <setting name="FirmwareFilePath" serializeAs="String"> 
       <value>test</value> 
      </setting> 
     </HawkConfigGUI.Properties.Settings> 
    </userSettings> 
</configuration> 

Sonra dosyasını alma ve tüm ayarları app değiştirilir (unutma:) Aşağıdaki gibi bir dosya üretir, hangi kurtarmak için dosyanın yolu ile Aktar kullanarak çalışır bir noktada .Save(). Bir şeyler ters giderse ayarlar geri döner. Ben başka cevaplar alamaz ve benim önceki çözüm memnun değildi vermedi beri

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

namespace HawkConfigGUI 
{ 
    public static class SettingsIO 
    { 
     private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger(); 

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

      var appSettings = Properties.Settings.Default; 
      try 
      { 
       // Open settings file as XML 
       var import = XDocument.Load(settingsFilePath); 
       // Get the <setting> elements 
       var settings = import.XPathSelectElements("//setting"); 
       foreach (var setting in settings) 
       { 
        string name = setting.Attribute("name").Value; 
        string value = setting.XPathSelectElement("value").FirstNode.ToString(); 

        try 
        { 
         appSettings[name] = value; // throws SettingsPropertyNotFoundException 
        } 
        catch (SettingsPropertyNotFoundException spnfe) 
        { 
         _logger.WarnException("An imported setting ({0}) did not match an existing setting.".FormatString(name), spnfe); 
        } 
        catch (SettingsPropertyWrongTypeException typeException) 
        { 
         _logger.WarnException(string.Empty, typeException); 
        } 
       } 
      } 
      catch (Exception exc) 
      { 
       _logger.ErrorException("Could not import settings.", exc); 
       appSettings.Reload(); // from last set saved, not defaults 
      } 
     } 

     internal static void Export(string settingsFilePath) 
     { 
      var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); 
      config.SaveAs(settingsFilePath); 
     } 
    } 
} 
+1

Birinin neden bu kadar kötü bir cevabı düşündüğünü ve birisinin "iyi" bir cevap üretmesini istediğini bilmek isterim. Tek söylemek istediğim, bu kodun * çalıştığı * ve sunulan başka bir çalışma çözümü olmadı. – Pat

+0

Bu arada, bu çözüm * app.config dosyasını işlemez *. Uygulama kapatıldığında dosyaya aktarılan user.config'in bellek içi sürümünü değiştirir. – Pat

İlgili konular