Laden...

Settings in Registry speichern

Erstellt von blackdynamic vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.599 Views
B
blackdynamic Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren
Settings in Registry speichern

Hallo Community,

ich habe in meinem Programm eine statische "Settings" Klasse, welche alle Einstellungen beinhaltet.
Der User soll die Möglichkeit haben, diese Einstellungen zu speichern.

Da sich das Speichern von statischen Klassen in einer XML-Datei aber als ziemlich kompliziert darstellt, habe ich mir überlegt, ob ich die Einstellungen nicht am besten einfach in die Registry schreiben sollte?

Könnt ihr mir eventuell sagen, wie ich das umsetzen kann?

Viele Grüße und danke schon mal im vorraus.
blacki

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo blackdynamic,

es ist nicht gerade ein Zeichen von einem guten Programmdesign wenn man eine statische Klasse in eine Datei serialisiert.

Aber das ist möglich. Dazu kannst du den BinaryFormatter oder _:::

Zudem kannst du dir das hier mal anschauen.
Persisting Application Settings in the .NET Framework
Die dort gezeigte Lösung ist um einiges sauberer als der Weg mit der statischen Klasse.

PS: Bitte beachte: [Hinweis] Wie poste ich richtig?
Mit einer kleinen Suchanfrage an Google hättest du einige Treffer finden können

Gruss
Michael

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo blackdynamic,

verwende besser [Tutorial] Das neue Konfigurationsmodell im .NET Framework 2.0.

herbivore

B
blackdynamic Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Hallo herbivore,

ja das hatte ich eigentlich auch vor.

Allerdings ist bei mir z.Z. folgendes Szenario:

Die Settings werden beim laden des Startfensters geladen.
Verändert werden sie allerdings in einem extra Fenster das "Einstellungen" heisst.
Nur das Fenster "Einstellungen" soll die Settings in der Konfiguration abspeichern können.

Wenn ich nun aber die Settings, welche ich im Startfenster geladen habe, an das "Einstellungen" Fenster übergebe, um das "Einstellungen" Fenster entsprechend den momentanen Einstellungen darzustellen, bekomme ich immer den Fehler, dass die Settings weniger Zugreifbar als die Methode sind, an die ich sie übergeben möchte. Die Settings sind ja private und da die Methode von einem anderen Fenster kommt, ist sie public.

Ich könnte natürlich auch einfach alle Einstellungen in public properties zwischenspeichern und dann aus meinem Startfenster heraus aufrufen, aber ich denke, dass ist "von hinten durch den Rücken ins Auge" oder?
Ich würde mich freuen, wenn ihr mir helfen könntet, das ganze ein wenig professioneller zu lösen.

Desweiteren würde mich mal interessieren, warum die Verwendung des Konfigurationsmodells besser ist, als die Verwendung der Registry?
Das ist eine reine Interessenfrage also wenn es zu aufwendig wäre das zu erklären ist es auch kein Problem.

Viele Grüße
blacki

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo blackdynamic,

die Ursache für

bekomme ich immer den Fehler, dass die Settings weniger Zugreifbar als die Methode sind, an die ich sie übergeben möchte. Die Settings sind ja private und da die Methode von einem anderen Fenster kommt, ist sie public.

hast du zutreffend beschrieben. Im Grunde wäre die Lösung einfach. Die Klasse müsste public sein. Ich vermute jedoch, dass du die Settings mit VS erstellst und die Zugriffsmodifier im generierten Code stehen, weshalb du sie nicht einfach so ändern kannst. Dazu kann ich leider nichts sagen, weil ich kein VS benutze. Aber vielleicht weiß jemand anders was hierzu.

warum die Verwendung des Konfigurationsmodells besser ist, als die Verwendung der Registry?

Die Registry hat verschiedene Nachteile: Dadurch, dass die Registry eine zentrale Stelle für alles ist, neigt sie dazu zuzumüllen mit teilweise negativen Auswirkungen für die Performance des ganzen Rechnern. Außerdem ist sie - auch für Admins - weniger transparent, weniger zugänglich und weniger handhabbar, als Settings, die unter den AppData-Verzeichnissen abgelegt werden. In einem AppData-Verzeichnis für die Anwendung ist alles nötige zusammen gefasst und nicht wie bei der Registry über verschiedene Zweige verstreut. Es gibt sicher noch weitere Gründe, aber ich denke, das sollte erstmal reichen. 😃

herbivore

T
94 Beiträge seit 2007
vor 13 Jahren

Wenn du wirklich die Standardanwendungs- bzw. -benutzereinstellungen verwendest, sind diese aus jeder Klasse heraus ansprechbar mittels.


Properties.Settings.Default.<DeineVariable>;

Schau dir dazu die vom Studio generierte Datei Settings.Designer.cs unterhalb des Property Ordners an.

699 Beiträge seit 2007
vor 13 Jahren

Desweiteren würde mich mal interessieren, warum die Verwendung des Konfigurationsmodells besser ist, als die Verwendung der Registry?

Da kann ich Dir auch noch ein Beispiel liefern. In einer Domain ( Active Directory ) Verwalteten Umgebung, wo die User Daten zentral auf dem Server gespeichert werden, hast Du das riesen Problem, das Du bei einem Wechsel des Rechner und einem Anmelden an der Domain nicht mehr die selben Settings haben wirst.

Wenn die Settings aber nach dem Konfigurationsmodell gespeichert wurden, interessiert es nicht, an welchem Rechner Du dich anmelden wirst, denn die Settings sind dann ja im User Verzeichnis zentral auf dem Server gespeichert und werden dort geladen.

Außerdem ist das Konfigurationsmodell einfacher zu verwenden als die Registry.
Ich hatte noch nie das bedürfnis Settings in der Registry zu speichern, seitdem ich das Konfigurationsmodell kenne.

Grüße Stephan

203 Beiträge seit 2006
vor 13 Jahren

ich hab dafür 2 Klassen und ein Interface geschrieben


public class RegistryHelper
    {
        private RegistryKey m_registryKey = null;
        private string m_registryPath = null;

        public RegistryHelper(RegistryKey registryKey, string registryPath)
        {
            this.RegistryKey = registryKey;
            this.RegistryPath = registryPath;
        }

        public RegistryKey ConfigurationStore
        {
            get { return this.RegistryKey.CreateSubKey(this.RegistryPath); }
        }

        public RegistryKey RegistryKey
        {
            get { return m_registryKey; }
            set { m_registryKey = value; }
        }

        public string RegistryPath
        {
            get { return m_registryPath; }
            set { m_registryPath = value; }
        }

        public string LoadString(string name, string def, bool create)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                return (string)key.GetValue(name, def);
            }
            finally
            {
                if (create && !HasValue(name))
                    SaveString(name, def);
                key.Close();
            }
        }

        public string[] LoadStringArray(string name, string[] def, bool create)
        {
            return this.LoadStringArray(name, def, ",", create);
        }

        public string[] LoadStringArray(string name, string[] def, string sep, bool create)
        {
            string s = this.LoadString(name, def != null ? string.Join(sep, def) : "", create);
            return s.Split(new string[] { sep }, StringSplitOptions.RemoveEmptyEntries);
        }

        public void SaveString(string name, string val)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                key.SetValue(name, val);
            }
            finally
            {
                key.Close();
            }
        }

        public int LoadInteger(string name, int def, bool create)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                return (int)key.GetValue(name, def);
            }
            finally
            {
                if (create && !HasValue(name))
                    this.SaveInteger(name, def);
                key.Close();
            }
        }

        public uint LoadDword(string name, uint def, bool create)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                return (uint)key.GetValue(name, def);
            }
            finally
            {
                if (create && !HasValue(name))
                    this.SaveDword(name, def);
                key.Close();
            }
        }

        public void SaveDword(string name, uint val)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                key.SetValue(name, val, RegistryValueKind.DWord);
            }
            finally
            {
                key.Close();
            }
        }

        public void SaveInteger(string name, int val)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                key.SetValue(name, val, RegistryValueKind.DWord);
            }
            finally
            {
                key.Close();
            }
        }

        public Type GetValueType(string name)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                RegistryValueKind kind = key.GetValueKind(name);
                if (kind == RegistryValueKind.DWord)
                    return typeof(int);
                else if (kind == RegistryValueKind.String)
                    return typeof(string);
                else
                    return typeof(object);
            }
            catch (System.IO.IOException) { return null; }
            finally
            {
                key.Close();
            }
        }

        public bool HasValue(string name)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                return key.GetValue(name) != null;
            }
            finally
            {
                key.Close();
            }
        }

        public void DeleteValue(string Name)
        {
            RegistryKey key = this.ConfigurationStore;
            try
            {
                key.DeleteValue(Name, false);
            }
            finally
            {
                key.Close();
            }
        }        
    }

public interface IConfiguration
    {
        uint LoadDword(string name, uint def, bool create);
        int LoadInteger(string name, int def, bool create);
        string LoadString(string name, string def, bool create);
        decimal LoadDecimal(string name, decimal def, bool create);
        string[] LoadString(string name, string[] def, bool create);

        void SaveDword(string name, uint val);
        void SaveInteger(string name, int val);
        void SaveString(string name, string val);
        void SaveDecimal(string name, decimal val);

        IConfiguration GetSection(string name);

        StringDictionary GetValues();
        StringDictionary GetValues(Strings names);
        Strings SectionNames { get; }
        Strings ValueNames { get; }
        Type GetValueType(string valueName);
    }


 public class RegConfiguration : Win32.RegistryHelper, IConfiguration
    {        
        public RegConfiguration(string registryPath)
            : base(Microsoft.Win32.Registry.LocalMachine, registryPath)
        {            
        }

        #region IConfiguration Members

        public decimal LoadDecimal(string name, decimal def, bool create)
        {
            decimal retval;
            if (!decimal.TryParse(this.LoadString(name, def.ToString(ThreadHelper.Culture), create), NumberStyles.Number, ThreadHelper.Culture, out retval))
                retval = def;
            return retval;
        }

        public void SaveDecimal(string name, decimal val)
        {
            this.SaveString(name, val.ToString(ThreadHelper.Culture));
        }

        public IConfiguration GetSection(string name)
        {
            return new RegConfiguration(Path.Combine(this.RegistryPath, name));
        }

        public Strings SectionNames
        {
            get
            {
                Strings strings = new Strings();
                strings.AddRange(this.ConfigurationStore.GetSubKeyNames());
                return strings;
            }
        }

        public Strings ValueNames
        {
            get
            {
                Strings strings = new Strings();
                strings.AddRange(this.ConfigurationStore.GetValueNames());
                return strings;
            }
        }
        
        public StringDictionary GetValues(Strings names)
        {
            return ConfigurationHelper.GetValues(this, names);
        }

        public StringDictionary GetValues()
        {
            return ConfigurationHelper.GetValues(this, null);
        }

        public string[] LoadString(string name, string[] def, bool create)
        {
            return ConfigurationHelper.LoadStringArray(this, name, def, create);
        }

        #endregion
    }

vielleicht hilft es dir ja. aber statisch würde ich die sache nicht halten.
eher ne normale klasse wie ich, die du dann ggf. global statisch zur verfügung stellst!

B
blackdynamic Themenstarter:in
51 Beiträge seit 2010
vor 13 Jahren

Wenn du wirklich die Standardanwendungs- bzw. -benutzereinstellungen verwendest, sind diese aus jeder Klasse heraus ansprechbar mittels.

  
Properties.Settings.Default.<DeineVariable>;  
  

Schau dir dazu die vom Studio generierte Datei Settings.Designer.cs unterhalb des Property Ordners an.

Vielen Dank.
Mit dieser Information kann ich mein Problem nun lösen.

Ich danke herbivore und Stipo, die mich überzeugt haben, nicht die die Registry zu verwenden.

esskar danke für die Hilfe, allerdings werde ich das Konfigurationsmodell verwenden.

Viele Grüße
blacki