Einstellungen des Programms speichern – Registry oder Users-Ordner? Bestes Vorgehen?

  • Allgemein

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Marcus Gräfe.

    Einstellungen des Programms speichern – Registry oder Users-Ordner? Bestes Vorgehen?

    Die Frage bezieht sich zwar auf VB.NET, ist aber allgemein gemeint. In meinem Programm möchte ich ein paar Grundeinstellungen des Programms (z. B. Fensterposition) abspeichern. Nun gibt es zwei Methoden, die sich (abgesehen von einer Datenbank) dafür eignen, der Users-Ordner von Windows (C:\Users\XY\...) oder die Registry. Bisher habe ich immer die Registry verwendet und dazu tendiere ich immer noch.

    Aber ist das noch der empfohlene Weg im Jahr 2020? Der Thread Registry vs. INI-Datei vs. Datenbank (Programmparameter speichern) beschäftigt sich auch mit dem Thema, allerdings ist der von 2013.

    Ich weiß, dass es "My.Settings" in VB gibt (wobei das "My" verpönt zu sein scheint), aber nur weil es damit einfach geht heißt ja nicht, dass es besser als die klassische Speicherung in der Registry ist. Oder doch?

    Wie ist eure Einschätzung?
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Die Settings scheinen mit da tatsächlich der beste Weg. Die liegen Standardmäßig im AppData Ordner des aktuellen Users.

    Falls du My.Settings nicht verwenden möchtest, kannst du natürlich auch eine eigene Klasse erstellen, und diese dann durch einen Serializer jagen, und das dann unter Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) bzw. LocalApplicationData Speichern.

    Wenn du vom User Unabhängig sein möchtest, deine Anwendung also für alle User auf dem PC bedienbar sein soll dann speicherst du unter Environment.GetFolderPath(Environment.SpecialForlders.CommonApplicationData). Damit kommst du im versteckten ProgrammData Ordner raus, der neben Program Files und Program Files x86 liegt. Da musst du jedoch darauf achten, dass du die Berechtigungen auf den Dateien entsprechend setzt:

    Hier hab ich eine .json Datei als Konfiguration für einen ASP.NET Web API Dienst erstellt, und danach Vollzugriff für "Jeder" bzw. "Everyone" auf Ordner und Datei gewährt.

    C#-Quellcode

    1. string jsonSettingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Company Services", "ServiceSettings.json");
    2. string jsonSettingsData = JsonConvert.SerializeObject(jsonSettingsProvider, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
    3. FileInfo jsonFile = new FileInfo(jsonSettingsPath);
    4. DirectoryInfo jsonsDirectory = Directory.CreateDirectory(jsonFile.Directory.FullName);
    5. File.WriteAllText(jsonSettingsPath, jsonSettingsData);
    6. Console.WriteLine("Set Permissions");
    7. DirectorySecurity directorySecurity = jsonsDirectory.GetAccessControl();
    8. FileSecurity fileSecurity = jsonFile.GetAccessControl();
    9. directorySecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, AccessControlType.Allow));
    10. fileSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, AccessControlType.Allow));
    11. jsonsDirectory.SetAccessControl(directorySecurity);
    12. jsonFile.SetAccessControl(fileSecurity);
    In dem Fall kann man My.Settings verwenden.
    Ich finde das ist die schnellste und einfachste Lösung.
    Wenn man zum Beispiel ein Programm auf „C:/Programme/Programmname“ installiert hat,
    hat man auch meistens keine Rechte zu schreiben.
    Deshalb kann man da INI-Settings vergessen!
    Außerdem habe ich gelesen das INI-Settings veraltet ist.
    Und ich persönlich hasse es wenn Programme neue Registry Einträge machen.
    Deshalb ist My.Settings die beste Möglichkeit.
    Visual Basic.NET 8o
    MS-SQL
    8o
    Danke euch beiden.

    Ich denke, ich werde es nun über My.Settings machen.

    EDIT: Ziemlich hässliche und umfangreiche Verzeichniserstellung bei Verwendung von My.Settings...
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Und wie wär es als Teil der oder einer extra XML-Datei?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Marcus Gräfe schrieb:

    Ich denke, ich werde es nun über My.Settings machen.


    Bedenke, das jeder User(Windows User) seine eigenen Settings hat, wie auch das wenn die App verschoben wird(falls du portabel bleiben willst), die settings wieder den Defaultwert haben, also nicht mit "umziehen". Ich bevorzuge, eine Datei in C:/ProgramData/Appname/(ProgramData ist ein hidden Directory). Sei es nun CSV, INI, XML oder sonstwas.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „NoIde“ ()

    Marcus Gräfe schrieb:

    Ziemlich hässliche und umfangreiche Verzeichniserstellung bei Verwendung von My.Settings...
    Nicht unbedingt.
    Bei mir sieht das ungfähr so aus, ich hoffe, Du störst Dich nicht an C#:

    C#-Quellcode

    1. // C:\ProgramData\
    2. string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\XXX\\";
    3. Directory.CreateDirectory(path);
    4. this.SettingsAll = DataAll.ReadSettings(path + "AllSettings.xml");
    5. // bzw.
    6. // C:\Users\Nutzer\AppData\Local\
    7. string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\XXX\\";
    8. Directory.CreateDirectory(path);
    9. this.SettingsUser = DataUser.ReadSettings(path + "UserSettings.xml");
    Da wird das lokale Verzeichnis sofort angelegt, wenn es noch nicht da ist. Testen auf Vorhandensein ist nicht erforderlich.
    Die Settings-Klasse hat eine static | Shared ReadSettings(path)-Prozedur, die entweder die gelesenen Settings oder die Inital-Belegung zurück gibt:
    Spoiler anzeigen

    C#-Quellcode

    1. /// <summary>
    2. /// Laden der Settings
    3. /// </summary>
    4. /// <param name="path">Pfad der XML-Datei</param>
    5. /// <returns>die geladenen Settings</returns>
    6. public static DataUser ReadSettings(string path)
    7. {
    8. DataUser settings = new DataUser();
    9. try
    10. {
    11. // Deserialize text file to a new object.
    12. using (StreamReader sr = new StreamReader(path))
    13. {
    14. XmlSerializer x = new XmlSerializer(settings.GetType());
    15. settings = (DataUser)x.Deserialize(sr);
    16. }
    17. }
    18. catch
    19. {
    20. // nix tun, die Settings-Instanz ist nicht valid,
    21. // es werden die Default-Werte zurückgegeben
    22. }
    23. settings.Path = path;
    24. return settings;
    25. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @VaporiZed Sprichst du die XML-Datenbank aus meinen anderen Thread an? Das wäre eine für alle Programmbenutzer, egal auf welchem Rechner (wenn die EXE im Netzwerk liegt). Die Einstellungen, um die es hier geht, sollen wirklich pro Benutzer sein.

    Aber eine eigene XML-Datei, ohne Verwendung von My.Settings, wird es wohl werden.

    @NoIde Das mit dem Umzug wird sich aber doch kaum vermeiden lassen, es sei denn, die Konfiguration ist im Anwendungsverzeichnis gespeichert, was im Regelfall nicht geht (Programme-Ordner nur Adminzugriff). Und in meinem Fall möchte ich wirklich benutzerbezogen sein, nicht rechnerbezogen. Es geht auch nur um ganz simple Einstellungen, die den Fensterzustand betreffen.

    @RodFromGermany Was ich meinte war, dass ich bei Verwendung von My.Settings den Pfad nicht mitbestimmen kann und ich dann in meinem Fall sowas habe:
    C:\Users\XXXXX\AppData\Roaming\Hersteller_des_Programms_–_Tolle_Software_fü\Programm.exe_Url_22v2bcdxpghz12oyveb1pprwxbfqsez2\1.0.0.0\

    Mir schwebt aber eher sowas vor:
    C:\Users\XXXXX\AppData\Roaming\HdP\Programm\
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    @Marcus Gräfe Zu My.Settings mit einem Speicherort und einem Dateinamen Deiner Wahl sieh Dir mal das Tut von @VB1963 an funktioniert problemlos:
    UserSettingsProvider (Persistieren von UserSettings)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke, schaue ich mir an. Ich habe hier übrigens noch einen netten Artikel zum Thema contra Registry gefunden (zwar etwas älter, aber sicher noch relevant): blog.codinghorror.com/was-the-windows-registry-a-good-idea/
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    NoIde schrieb:


    Bedenke, das jeder User(Windows User) seine eigenen Settings hat, wie auch das wenn die App verschoben wird(falls du portabel bleiben willst), die settings wieder den Defaultwert haben, also nicht mit "umziehen". Ich bevorzuge, eine Datei in C:/ProgramData/Appname/(ProgramData ist ein hidden Directory). Sei es nun CSV, INI, XML oder sonstwas.

    Ist das so? Man kann doch zwischen "Benutzer" und "Anwendung" hin und her schalten, je Settingeintrag.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    ich hab das damals so verstanden, dass die Settings dafür erfunden wurden, dass man nicht mehr die Registry vollmüllen muss.
    Ok, nun müllt man ein Appdata-Verzeichnis voll, aber das hat glaub weniger SeitenEffekte, und ist auch einer Aufräum-Session leichter zugänglich.
    Andere Frage ist, ob man für Registry-Schreibzugriffe nicht besondere Rechte braucht, die der Endnutzer eiglich nicht haben soll.
    Settings hingegen werden immer so angelegt, dasses funzt.

    ErfinderDesRades schrieb:

    und ist auch einer Aufräum-Session leichter zugänglich

    Das ist auf jeden Fall ein Vorteil. Nach einer Deinstallation räume ich da immer manuell auf, in der Registry niemals.

    ErfinderDesRades schrieb:

    Andere Frage ist, ob man für Registry-Schreibzugriffe nicht besondere Rechte braucht

    Auch in der Registry gibt es einen Bereich für den aktuellen User, daher werden dort sicher alle Rechte vorliegen (reine Vermutung). Aber ich habe noch nie davon gehört oder das so erlebt, dass ein Programm nicht beliebig in der Registry rumschreiben darf, egal was für Rechte der User hat.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum

    Marcus Gräfe schrieb:

    Aber ich habe noch nie davon gehört oder das so erlebt, dass ein Programm nicht beliebig in der Registry rumschreiben darf, egal was für Rechte der User hat.
    Oh doch.
    Viele Firmen verhindern das mit Group-Policy-Einträgen.

    Da brauchst du für jede Installation einen Admin-User.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Gilt das denn auch für den CURRENT_USER-Zweig?

    Auf jeden Fall bin ich von der Idee "Registry" nun weg und werde die Daten auf jeden Fall als XML im Users/AppData-Verzeichnis speichern. Wie genau, das überlege ich mir noch.

    Ich habe allerdings ein Programm, da lege ich Infos in der Registry ab, weil diese versteckt sein sollen. Es geht da um einen Demoversionsschutz. Auf Dateiebene wäre der zu leicht auszuhebeln.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    Naja, auf Registry-Ebene auch. Wenn man da zB. einfach dein Programm als ThinApp (VM Ware) generiert, sieht man ja, was sie alles am System ändert.
    Das ist eher security through obscurity.
    Die My.Settings in AppData haben mMn. den Vorteil, dass du einfach neue Settings einführen kannst und bei neuen Versionen die Neuen Settings in einen neuen Ordner/neue Datei wandern und du dann entscheiden kannst, wie du mit den Differenzen umgehst, einfach die AltDaten migrierst, oder mit aus der IDE vorgegebenen Defaultwerten neu startest. Das hat ja MS alles bereits da vorgesehen, oder dass man selbst was frickeln muss.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D

    MemoAnMichSelbst schrieb:

    Naja, auf Registry-Ebene auch.

    In meinen Augen für den normalen User aber wesentlich komplizierter und damit für mich sicherer. Ich kenne genug Leute, die keinen Schimmer haben, dass es überhaupt eine Registry gibt, aber sicher eine Datei finden und löschen könnten.

    MemoAnMichSelbst schrieb:

    Das ist eher security through obscurity

    Absolut! Allerdings gibt es keine Möglichkeit, das wirklich unknackbar zu machen. Etwas sicherer wäre es nur mit einer Online-Prüfung. Allerdings ist das gemeinte Programm zu einer Zeit entwickelt worden, wo gerade Firmenrechner noch nicht wie heute dauerhaft Internetzugang hatten (also falls überhaupt).

    MemoAnMichSelbst schrieb:

    Das hat ja MS alles bereits da vorgesehen, oder dass man selbst was frickeln muss

    Richtig, wobei ich viele der Features gar nicht brauche, bei dem simplen Anwendungsfall, den ich derzeit habe.

    Gonger96 schrieb:

    dass du an Settings an Controls binden kannst

    Ist mir vielfach zu unflexibel. Z. B. merke ich mir den WindowState, möchte aber nicht den Minimiert-Zustand speichern (sondern in dem Fall den davor verwendeten). Also zumindest den Speichern-Code brauche ich.
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum