Wie kann ich Anwendungseinstellungen in einer Windows Forms-Anwendung speichern?

582

Was ich erreichen möchte, ist sehr einfach: Ich habe eine Windows Forms-Anwendung (.NET 3.5), die einen Pfad zum Lesen von Informationen verwendet. Dieser Pfad kann vom Benutzer mithilfe des von mir bereitgestellten Optionsformulars geändert werden.

Jetzt möchte ich den Pfadwert zur späteren Verwendung in einer Datei speichern. Dies wäre eine der vielen Einstellungen, die in dieser Datei gespeichert sind. Diese Datei würde sich direkt im Anwendungsordner befinden.

Ich verstehe, dass drei Optionen verfügbar sind:

  • ConfigurationSettings-Datei (appname.exe.config)
  • Registrierung
  • Benutzerdefinierte XML-Datei

Ich habe gelesen, dass die .NET-Konfigurationsdatei nicht zum Speichern von Werten vorgesehen ist. Was die Registrierung betrifft, möchte ich mich so weit wie möglich davon entfernen.

Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei verwenden sollte, um Konfigurationseinstellungen zu speichern?

Wenn ja, würde ich gerne ein Codebeispiel dafür sehen (C #).

Ich habe andere Diskussionen zu diesem Thema gesehen, aber es ist mir immer noch nicht klar.

Betankt
quelle
Ist dies eine .NET WinForms-Anwendung? Wenn ja, auf welcher Version von .NET entwickeln Sie?
Portman
1
Ja, es handelt sich um eine WinForms-Anwendung von .NET Framework Version 3.5.
Betankt am
1
Benötigen Sie gespeicherte Passwörter oder Geheimnisse ? Möglicherweise erfordert jede Verschlüsselung
Kiquenet

Antworten:

593

Wenn Sie mit Visual Studio arbeiten, ist es ziemlich einfach, dauerhafte Einstellungen zu erhalten. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt und wählen Sie Eigenschaften. Wählen Sie die Registerkarte Einstellungen und klicken Sie auf den Hyperlink, wenn keine Einstellungen vorhanden sind.

Verwenden Sie die Registerkarte Einstellungen, um Anwendungseinstellungen zu erstellen. Visual Studio erstellt die Dateien Settings.settingsund Settings.Designer.settingsdas enthält die Singleton - Klasse Settingsgeerbt Application . Sie können über Ihren Code auf diese Klasse zugreifen, um Anwendungseinstellungen zu lesen / schreiben:

Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file

Diese Technik ist sowohl für Konsolen, Windows Forms als auch für andere Projekttypen anwendbar.

Beachten Sie, dass Sie die Bereichseigenschaft Ihrer Einstellungen festlegen müssen . Wenn Sie Anwendungsbereich auswählen, ist Settings.Default. <Ihreigenschaft> schreibgeschützt.

Referenz: Gewusst wie: Schreiben von Benutzereinstellungen zur Laufzeit mit C # - Microsoft Docs

aku
quelle
2
Wenn ich eine Lösung habe, gilt dies für die gesamte Lösung oder für jedes Projekt?
franko_camron
8
@Four: Ich habe hier ein .NET 4.0 WinApp-Projekt und meine SomeProperty ist nicht schreibgeschützt. Settings.Default.SomeProperty = 'value'; Settings.Default.Save();klappt wunderbar. Oder liegt das daran, dass ich Benutzereinstellungen habe?
Doekman
4
@Four: Als ich eine Einstellung von Benutzer in Anwendungsbereich geändert und die Datei gespeichert habe, habe ich im generierten Code gesehen, dass der Setter verschwunden ist. Dies passiert auch mit Client-Profil 4.0 ...
Doekman
3
@ Vier: toller Link, obwohl deine Aussage, dass das Settings.Default.Save()nichts tut, falsch ist. Wie @aku in der Antwort feststellt, sind die Einstellungen für den App-Bereich schreibgeschützt: Speichern ist für sie unwirksam. Verwenden Sie diesen benutzerdefinierten PortableSettingsProvider , um die Einstellungen für den Benutzerbereich in der app.config zu speichern, in der sich die exe anstelle der im AppData-Ordner des Benutzers befindet. Nein, im Allgemeinen nicht gut, aber ich verwende es während der Entwicklung, um die gleichen Einstellungen von Kompilierung zu Kompilierung zu verwenden (ohne sie werden bei jeder Kompilierung neue eindeutige Benutzerordner erstellt).
Elritze
7
Ab sofort können Sie mit .NET 3.5 einfach Settings.Default.SomeProperty verwenden, um einen Wert zuzuweisen und eine starke Typumwandlung zu erhalten. Um anderen Zeit zu sparen (ich habe eine Weile gebraucht, um dies herauszufinden), müssen Sie entweder Properties.Settings.Default eingeben oder mithilfe von YourProjectNameSpace.Settings am Anfang Ihrer Datei hinzufügen. "Einstellungen" allein ist nicht definiert / gefunden.
Eselk
95

Wenn Sie vorhaben, in einer Datei im selben Verzeichnis wie Ihre ausführbare Datei zu speichern, finden Sie hier eine nette Lösung, die das JSON- Format verwendet:

using System;
using System.IO;
using System.Web.Script.Serialization;

namespace MiscConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            MySettings settings = MySettings.Load();
            Console.WriteLine("Current value of 'myInteger': " + settings.myInteger);
            Console.WriteLine("Incrementing 'myInteger'...");
            settings.myInteger++;
            Console.WriteLine("Saving settings...");
            settings.Save();
            Console.WriteLine("Done.");
            Console.ReadKey();
        }

        class MySettings : AppSettings<MySettings>
        {
            public string myString = "Hello World";
            public int myInteger = 1;
        }
    }

    public class AppSettings<T> where T : new()
    {
        private const string DEFAULT_FILENAME = "settings.json";

        public void Save(string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(this));
        }

        public static void Save(T pSettings, string fileName = DEFAULT_FILENAME)
        {
            File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(pSettings));
        }

        public static T Load(string fileName = DEFAULT_FILENAME)
        {
            T t = new T();
            if(File.Exists(fileName))
                t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
            return t;
        }
    }
}
Trevor
quelle
Ja, ändern Sie DEFAULT_FILENAME in einen absoluten Pfad, wenn Sie in einem anderen Verzeichnis speichern möchten. Ich denke, es ist am häufigsten, die Datei im selben Verzeichnis wie die Anwendung oder in einem Unterverzeichnis zu speichern, wenn Sie sie nicht in der Registrierung speichern.
Trevor
Oh, vielleicht wäre die bessere Option, die Einstellungsdatei im Appdata-Ordner des Benutzers zu speichern.
Trevor
1
Keine Notwendigkeit zu ändern DEFAULT_FILENAME, rufen Sie einfach an settings.Save(theFileToSaveTo); Alle Kappen zu sein, DEFAULT_FILENAMEsoll eine Konstante sein . Wenn Sie eine Lese- / Schreibeigenschaft wünschen, erstellen Sie eine und lassen Sie sie vom Konstruktor festlegen DEFAULT_FILENAME. Lassen Sie dann den Standardargumentwert sein null, testen Sie dies und verwenden Sie Ihre Eigenschaft als Standardwert. Es ist etwas tippender, bietet Ihnen aber eine Standardschnittstelle.
Jesse Chisholm
10
Sie müssen referenzieren, System.Web.Extensions.dllwenn Sie dies noch nicht getan haben.
TEK
9
Ich habe eine ganze Bibliothek basierend auf dieser Antwort mit vielen Verbesserungen erstellt und sie in nuget verfügbar gemacht: github.com/Nucs/JsonSettings
NucS
67

Die Registrierung ist ein No-Go. Sie sind sich nicht sicher, ob der Benutzer, der Ihre Anwendung verwendet, über ausreichende Rechte zum Schreiben in die Registrierung verfügt.

Sie können die app.configDatei zum Speichern von Einstellungen auf Anwendungsebene verwenden (die für jeden Benutzer, der Ihre Anwendung verwendet, gleich sind).

Ich würde benutzerspezifische Einstellungen in einer XML-Datei speichern, die im isolierten Speicher oder im Verzeichnis SpecialFolder.ApplicationData gespeichert würde .

Darüber hinaus ist es ab .NET 2.0 möglich, Werte wieder in der app.configDatei zu speichern.

Frederik Gheysels
quelle
8
Verwenden Sie jedoch die Registrierung, wenn Sie Einstellungen pro Anmeldung / Benutzer wünschen.
thenonhacker
19
Die Registrierung ist nicht portble
Kb.
10
@thenonhacker: Oder verwenden Sie Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData)
Kenny Mann
4
In die Benutzerregistry kann geschrieben werden (viele Programme schreiben dort Informationen, und Benutzerberechtigungen sind nie ein Problem). Der Vorteil der Verwendung der Registrierung gegenüber der Verwendung von Einstellungen besteht darin, dass mehrere Anwendungen, die denselben Ordner verwenden (z. B. ein Setup-Programm und ein Anwendungsprogramm), nicht dieselben Einstellungen verwenden.
Kesty
3
Der Hauptnachteil der Registrierung ist die schwierige Möglichkeit, Einstellungen auf einen anderen PC zu exportieren / kopieren. Ich bin jedoch nicht einverstanden mit "Sie sind sich nicht sicher, ob der Benutzer, der Ihre Anwendung verwendet, über ausreichende Rechte zum Schreiben in die Registrierung verfügt" - In HKEY_CURRENT_USER haben Sie immer Rechte zum Schreiben. Es kann abgelehnt werden, aber das Dateisystem kann auch für den aktuellen Benutzer nicht zugänglich sein (alle möglichen TEMP-Ordner usw.).
i486
20

Die ApplicationSettingsKlasse unterstützt das Speichern von Einstellungen in der Datei app.config nicht . Das ist sehr beabsichtigt; Anwendungen, die mit einem ordnungsgemäß gesicherten Benutzerkonto ausgeführt werden (z. B. Vista UAC), haben keinen Schreibzugriff auf den Installationsordner des Programms.

Sie können das System mit der ConfigurationManagerKlasse bekämpfen . Die triviale Problemumgehung besteht jedoch darin, in den Einstellungsdesigner zu wechseln und den Bereich der Einstellung in Benutzer zu ändern. Wenn dies zu Schwierigkeiten führt (z. B. ist die Einstellung für jeden Benutzer relevant), sollten Sie Ihre Optionsfunktion in ein separates Programm einfügen, damit Sie nach der Eingabeaufforderung zur Erhöhung von Berechtigungen fragen können. Oder verzichten Sie auf eine Einstellung.

Hans Passant
quelle
Könnten Sie bitte Ihren letzten Satz erweitern? Fragen Sie nach der Höhe, um app.config zu schreiben, oder um eine separate Anwendung zu schreiben, die die Home-Ordner aller Benutzer durchläuft. Suchen Sie nach user.config und bearbeiten Sie diese.
CannibalSmith
2
Das separate Programm erfordert ein Manifest, um nach einer Erhöhung zu fragen. Google 'asinvoker requireeadministrator', um die richtige Syntax zu finden. Das Bearbeiten von user.config ist weder praktisch noch notwendig.
Hans Passant
18

Das Argument registry / configurationSettings / XML scheint immer noch sehr aktiv zu sein. Ich habe sie alle verwendet, während die Technologie Fortschritte gemacht hat, aber mein Favorit basiert auf dem System von Threed in Kombination mit isoliertem Speicher .

Das folgende Beispiel ermöglicht das Speichern von Objekten mit dem Namen properties in einer Datei im isolierten Speicher. Sowie:

AppSettings.Save(myobject, "Prop1,Prop2", "myFile.jsn");

Eigenschaften können wiederhergestellt werden mit:

AppSettings.Load(myobject, "myFile.jsn");

Dies ist nur ein Beispiel, das keine Best Practices enthält.

internal static class AppSettings
{
    internal static void Save(object src, string targ, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = src.GetType();

        string[] paramList = targ.Split(new char[] { ',' });
        foreach (string paramName in paramList)
            items.Add(paramName, type.GetProperty(paramName.Trim()).GetValue(src, null));

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify.
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write((new JavaScriptSerializer()).Serialize(items));
            }

        }
        catch (Exception) { }   // If fails - just don't use preferences
    }

    internal static void Load(object tar, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = tar.GetType();

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
            using (StreamReader reader = new StreamReader(stream))
            {
                items = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(reader.ReadToEnd());
            }
        }
        catch (Exception) { return; }   // If fails - just don't use preferences.

        foreach (KeyValuePair<string, object> obj in items)
        {
            try
            {
                tar.GetType().GetProperty(obj.Key).SetValue(tar, obj.Value, null);
            }
            catch (Exception) { }
        }
    }
}
Boczek
quelle
1
Oder noch besser; Verwenden Sie DataContractJsonSerializer
Boczek
16

Ich wollte eine Bibliothek teilen, die ich dafür gebaut habe. Es ist eine winzige Bibliothek, aber eine große Verbesserung (IMHO) gegenüber .settings-Dateien.

Die Bibliothek heißt Jot (GitHub) . Hier ist ein alter Artikel von The Code Project, den ich darüber geschrieben habe.

So würden Sie es verwenden, um die Größe und Position eines Fensters zu verfolgen:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

Der Vorteil im Vergleich zu .settings-Dateien: Es gibt erheblich weniger Code und es ist viel weniger fehleranfällig, da Sie jede Eigenschaft nur einmal erwähnen müssen .

Bei Einstellungsdateien müssen Sie jede Eigenschaft fünfmal erwähnen : einmal, wenn Sie die Eigenschaft explizit erstellen, und weitere viermal im Code, der die Werte hin und her kopiert.

Speicher, Serialisierung usw. sind vollständig konfigurierbar. Wenn die Zielobjekte von einem IoC- Container erstellt werden, können Sie [[einbinden] [], sodass die Verfolgung automatisch auf alle aufgelösten Objekte angewendet wird. Alles, was Sie tun müssen, um eine Eigenschaft dauerhaft zu machen, ist ein [Trackingable] zu schlagen. Attribut darauf.

Es ist hochgradig konfigurierbar und Sie können Folgendes konfigurieren: - wenn Daten global oder für jedes verfolgte Objekt beibehalten und angewendet werden - wie sie serialisiert werden - wo sie gespeichert werden (z. B. Datei, Datenbank, Online, isolierter Speicher, Registrierung) - Regeln, die die Anwendung abbrechen können / persistente Daten für eine Eigenschaft

Vertrauen Sie mir, die Bibliothek ist erstklassig!

anakisch
quelle
14

Eine einfache Möglichkeit besteht darin, ein Konfigurationsdatenobjekt zu verwenden, es als XML-Datei mit dem Namen der Anwendung im lokalen Ordner zu speichern und beim Start zurückzulesen.

Hier ist ein Beispiel zum Speichern der Position und Größe eines Formulars.

Das Konfigurationsdatenobjekt ist stark typisiert und einfach zu verwenden:

[Serializable()]
public class CConfigDO
{
    private System.Drawing.Point m_oStartPos;
    private System.Drawing.Size m_oStartSize;

    public System.Drawing.Point StartPos
    {
        get { return m_oStartPos; }
        set { m_oStartPos = value; }
    }

    public System.Drawing.Size StartSize
    {
        get { return m_oStartSize; }
        set { m_oStartSize = value; }
    }
}

Eine Manager-Klasse zum Speichern und Laden:

public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configuration file
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configuration file
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}

Jetzt können Sie eine Instanz erstellen und in den Lade- und Schließereignissen Ihres Formulars verwenden:

    private CConfigMng oConfigMng = new CConfigMng();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load configuration
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save configuration
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }

Die erstellte XML-Datei ist auch lesbar:

<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>
Dieter Meemken
quelle
1
Ich habe dies in der Entwicklung großartig funktioniert, aber wenn ich die Anwendung bereitstelle, hat der durchschnittliche Benutzer keinen Zugriff auf den c:\program files\my applicationOrdner, so dass das Speichern von Einstellungen einen Fehler auslöst. Ich möchte stattdessen die XML-Datei in AppData speichern, habe mich aber nur gefragt, ob es einen offensichtlichen Weg gibt, um dieses Problem zu umgehen, da dieser Ansatz für Sie anscheinend funktioniert hat.
Philip Stratford
@PhilipStratford Da es sich nur um eine normale Datei handelt, können Sie sie überall speichern. Suchen Sie einfach einen Ort mit Schreibzugriff.
Dieter Meemken
@PhilipStratford Möglicherweise ist der AppData-Ordner eine Option für Sie. Siehe C #, um den Pfad von% AppData% abzurufen , wie von Kite erwähnt .
Dieter Meemken
Vielen Dank, ich habe dies bereits implementiert und die XML-Datei im AppDate-Ordner gespeichert. Ich habe mich nur gefragt, ob es eine einfache Möglichkeit gibt, es gemäß Ihrem Beispiel im Ordner der Anwendung zu speichern, da ich davon ausgegangen bin, dass Sie es zum Laufen gebracht haben. Keine Sorge, der AppData-Ordner ist wahrscheinlich sowieso ein besserer Ort!
Philip Stratford
5

Andere Optionen, anstatt eine benutzerdefinierte XML-Datei zu verwenden, können wir ein benutzerfreundlicheres Dateiformat verwenden: JSON- oder YAML-Datei.

  • Wenn Sie .NET 4.0 dynamic verwenden, ist diese Bibliothek sehr einfach zu verwenden (Serialisierung, Deserialisierung, Unterstützung verschachtelter Objekte und Reihenfolge der Ausgabe nach Ihren Wünschen + Zusammenführen mehrerer Einstellungen zu einer). JsonConfig (Verwendung entspricht ApplicationSettingsBase)
  • Für die .NET YAML-Konfigurationsbibliothek ... Ich habe keine gefunden, die so einfach zu verwenden ist wie JsonConfig

Sie können Ihre Einstellungsdatei in mehreren speziellen Ordnern (für alle Benutzer und pro Benutzer) speichern, wie hier aufgeführt. Environment.SpecialFolder Enumeration und mehrere Dateien (standardmäßig schreibgeschützt, pro Rolle, pro Benutzer usw.)

Wenn Sie mehrere Einstellungen verwenden möchten, können Sie diese Einstellungen zusammenführen: Beispiel: Zusammenführen von Einstellungen für Standard + BasicUser + AdminUser. Sie können Ihre eigenen Regeln verwenden: Die letzte überschreibt den Wert usw.

Drachen
quelle
4

"Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei verwenden sollte, um Konfigurationseinstellungen zu speichern?" Nein, nicht unbedingt. Wir verwenden SharpConfig für solche Operationen.

Zum Beispiel, wenn eine Konfigurationsdatei so ist

[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment

Wir können solche Werte abrufen

var config = Configuration.LoadFromFile("sample.cfg");
var section = config["General"];

string someString = section["SomeString"].StringValue;
int someInteger = section["SomeInteger"].IntValue;

Es ist kompatibel mit .NET 2.0 und höher. Wir können Konfigurationsdateien im laufenden Betrieb erstellen und später speichern.

Quelle: http://sharpconfig.net/
GitHub: https://github.com/cemdervis/SharpConfig

Turker Tunali
quelle
3

Soweit ich das beurteilen kann, unterstützt .NET dauerhafte Einstellungen mithilfe der integrierten Funktion für Anwendungseinstellungen:

Mit der Funktion "Anwendungseinstellungen" von Windows Forms können Sie auf einfache Weise benutzerdefinierte Anwendungs- und Benutzereinstellungen auf dem Clientcomputer erstellen, speichern und verwalten. Mit den Windows Forms-Anwendungseinstellungen können Sie nicht nur Anwendungsdaten wie Datenbankverbindungszeichenfolgen, sondern auch benutzerspezifische Daten wie Benutzeranwendungseinstellungen speichern. Mit Visual Studio oder benutzerdefiniertem verwaltetem Code können Sie neue Einstellungen erstellen, diese lesen und auf die Festplatte schreiben, sie an Eigenschaften in Ihren Formularen binden und Einstellungsdaten vor dem Laden und Speichern überprüfen. - http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx

Jacob
quelle
2
Nicht wahr .. siehe Akus Antwort oben. Es ist möglich mit Settings und ApplicationSettingsBase
Gishu
2

Manchmal möchten Sie diese Einstellungen entfernen, die in der herkömmlichen Datei web.config oder app.config gespeichert sind. Sie möchten eine genauere Kontrolle über die Bereitstellung Ihrer Einstellungseinträge und das getrennte Daten-Design. Oder Sie müssen das Hinzufügen neuer Einträge zur Laufzeit aktivieren.

Ich kann mir zwei gute Möglichkeiten vorstellen:

  • Die stark typisierte Version und
  • Die objektorientierte Version.

Der Vorteil der stark typisierten Version sind die stark typisierten Einstellungsnamen und -werte. Es besteht kein Risiko, Namen oder Datentypen zu vermischen. Der Nachteil ist, dass mehr Einstellungen codiert werden müssen, die zur Laufzeit nicht hinzugefügt werden können.

Bei der objektorientierten Version besteht der Vorteil darin, dass zur Laufzeit neue Einstellungen hinzugefügt werden können. Sie haben jedoch keine stark typisierten Namen und Werte. Muss mit String-IDs vorsichtig sein. Der Datentyp muss früher gespeichert werden, wenn ein Wert abgerufen wird.

Den Code der beiden voll funktionsfähigen Implementierungen finden Sie HIER .

user3130351
quelle
2

Ja, es ist möglich, die Konfiguration zu speichern - aber es hängt ziemlich stark davon ab, wie Sie sich dafür entscheiden. Lassen Sie mich die technischen Unterschiede beschreiben, damit Sie die Optionen verstehen, die Sie haben:

Zunächst müssen Sie unterscheiden, ob Sie applicationSettings oder AppSettings in Ihrer Datei *.exe.config(auch bekannt als App.configin Visual Studio) verwenden möchten. Hier werden grundlegende Unterschiede beschrieben .

Beide bieten verschiedene Möglichkeiten zum Speichern von Änderungen:

  • Mit den AppSettings können Sie direkt in die Konfigurationsdatei lesen und schreiben (via config.Save(ConfigurationSaveMode.Modified);, wobei config als definiert ist config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);).

  • Die applicationSettings ermöglichen das Lesen, aber wenn Sie Änderungen (über Properties.Settings.Default.Save();) schreiben , werden diese auf Benutzerbasis geschrieben und an einem bestimmten Ort (z C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0. B. ) gespeichert . Wie Hans Passant in seiner Antwort erwähnte , liegt dies daran, dass ein Benutzer normalerweise eingeschränkte Rechte an Programmdateien hat und nicht darauf schreiben kann, ohne die UAC-Eingabeaufforderung aufzurufen. Ein Nachteil ist, dass Sie beim Hinzufügen von Konfigurationsschlüsseln in Zukunft diese mit jedem Benutzerprofil synchronisieren müssen.

Hinweis: Wie in der Frage erwähnt, gibt es eine dritte Option: Wenn Sie die Konfigurationsdatei als XML-Dokument behandeln, können Sie sie mithilfe der System.Xml.Linq.XDocumentKlasse laden, ändern und speichern . Es ist nicht erforderlich, eine benutzerdefinierte XML-Datei zu verwenden. Sie können die vorhandene Konfigurationsdatei lesen. Zum Abfragen von Elementen können Sie sogar Linq-Abfragen verwenden. Ich habe ein Beispiel gegeben hier , um die Funktion überprüfen GetApplicationSettinges in der Antwort.

Wenn Sie benötigen Verschlüsselung , um Ihre Werte zu schützen, überprüfen Sie diese Antwort.

Matt
quelle
Vielen Dank für diese hervorragende Antwort.
NoChance
2
@NoChance - Gern geschehen, froh, dass ich Ihnen helfen konnte!
Matt
Nett! Endlich alles herausgefunden 😂😂😂
Momoro
1
@Momoro - gut zu hören! ;-)
Matt
1
public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}
Paul - Soura Tech LLC
quelle