654 Stimmen

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

Was ich erreichen möchte, ist sehr einfach: Ich habe eine Windows Forms (.NET 3.5) Anwendung, die einen Pfad zum Lesen von Informationen verwendet. Dieser Pfad kann vom Benutzer geändert werden, indem er das von mir bereitgestellte Optionsformular verwendet.

Nun 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 werden. Diese Datei würde sich direkt im Anwendungsordner befinden.

Soweit ich weiß, gibt es drei Möglichkeiten:

  • KonfigurationsEinstellungsdatei (appname.exe.config)
  • Registry
  • Benutzerdefinierte XML-Datei

Ich habe gelesen, dass die .NET-Konfigurationsdatei nicht dafür vorgesehen ist, Werte in ihr zu speichern. Was die Registrierung betrifft, möchte ich so weit wie möglich davon wegkommen.

Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei verwenden sollte, um die 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.

20voto

Matt Punkte 23047

Ja, es ist möglich, zu speichern die Konfiguration - aber das hängt weitgehend von der Art und Weise ab, wie Sie es tun wollen. Lassen Sie mich die technischen Unterschiede beschreiben, damit Sie die Optionen, die Sie haben, verstehen können:

Zunächst müssen Sie unterscheiden, ob Sie die applicationSettings o AppEinstellungen in Ihrem *.exe.config (alias App.config in Visual Studio) Datei - es gibt grundlegende Unterschiede, wird hier beschrieben .

Beide bieten unterschiedliche Möglichkeiten, Änderungen zu speichern:

  • El AppEinstellungen ermöglichen das Lesen und Schreiben direkt in die Konfigurationsdatei über config.Save(ConfigurationSaveMode.Modified); wobei config definiert ist als:
    config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

  • El applicationSettings zu lesen erlauben, aber wenn Sie Änderungen schreiben (über Properties.Settings.Default.Save(); ) wird sie für jeden Benutzer einzeln geschrieben und an einem speziellen Ort gespeichert (z.B. C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0 ). Unter Hans Passant erwähnt in seiner Antwort, liegt dies daran, dass ein Benutzer in der Regel eingeschränkte Rechte für die Programmdateien hat und nicht in diese schreiben kann, ohne die UAC-Eingabeaufforderung aufzurufen. Ein Nachteil ist, dass Sie, wenn Sie in Zukunft Konfigurationsschlüssel hinzufügen, diese mit jedem Benutzerprofil synchronisieren müssen.

Aber es gibt noch eine Reihe anderer Möglichkeiten:

  • Seit .NET Core (und .NET 5 und 6) ist ein 3. Option ist die appsettings.json Datei, die die Konfigurationsabstraktion von Microsoft verwendet. Aber normalerweise benutzt WinForms sie nicht, deshalb erwähne ich sie nur der Vollständigkeit halber. Wie auch immer, hier sind einige Referenzen wie man lesen y schreiben. die Werte. Alternativ können Sie auch Newtonsoft JSON zum Lesen und Schreiben el appsettings.json Datei, aber sie ist nicht darauf beschränkt: Sie können mit dieser Methode auch Ihre eigenen json-Dateien erstellen.

  • Wie in der Frage erwähnt, gibt es eine 4. Möglichkeit: Wenn Sie die Konfigurationsdatei als XML-Dokument, können Sie laden, ändern und speichern, indem Sie die System.Xml.Linq.XDocument Klasse. Es ist nicht erforderlich, eine benutzerdefinierte XML-Datei zu verwenden, Sie können die vorhandene Konfigurationsdatei lesen; für die Abfrage von Elementen können Sie sogar Linq-Abfragen verwenden. Ich habe ein Beispiel gegeben aquí überprüfen Sie die Funktion GetApplicationSetting dort in der Antwort.

  • A 5. Option ist die Speicherung von Einstellungen in der Registrierung. Wie Sie das tun können, wird beschrieben aquí .

  • Und nicht zuletzt gibt es eine 6. Möglichkeit : Sie können die Werte in der Umwelt (Systemumgebung oder Umgebung Ihres Kontos). Geben Sie in den Windows-Einstellungen (das Zahnrad im Windows-Menü) in der Suchleiste "Umgebung" ein und fügen Sie sie dort hinzu oder bearbeiten Sie sie. Um sie zu lesen, verwenden Sie
    var myValue = Environment.GetEnvironmentVariable("MyVariable"); .
    Beachten Sie, dass Ihre Anwendung normalerweise neu gestartet werden muss, um die aktualisierten Umgebungseinstellungen zu erhalten.

Wenn Sie benötigen Verschlüsselung zum Schutz Ihrer Werte, auschecken este Antwort. Sie beschreibt, wie man Microsofts DPAPI verwendet, um Werte verschlüsselt zu speichern.

Und wenn Sie Ihre eigenen Dateien, ob XML oder JSON, unterstützen wollen, könnte es nützlich sein, das Verzeichnis der laufenden Assembly zu kennen:

var assemblyDLL = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyDirectory = System.IO.Path.GetDirectoryName(assemblyDLL.Location);

Sie können verwenden assemblyDirectory als Basisverzeichnis zum Speichern Ihrer Dateien.

18voto

Boczek Punkte 181

Das Argument registry/configurationSettings/XML scheint immer noch sehr aktiv zu sein. Ich habe sie alle verwendet, da die Technologie sich weiterentwickelt hat, aber mein Favorit basiert auf Threed's System kombiniert mit Isolierte Lagerung .

Das folgende Beispiel ermöglicht die Speicherung eines Objekts mit dem Namen properties in einer Datei im isolierten Speicher. Zum Beispiel:

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

Die Eigenschaften können mit wiederhergestellt werden:

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

Es handelt sich nur um ein Beispiel, das nicht auf bewährte Verfahren schließen lässt.

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) { }
        }
    }
}

18voto

Dieter Meemken Punkte 1845

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 es beim Start wieder einzulesen.

Hier ist ein Beispiel für die Speicherung 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 Managerklasse 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();
    }

Und die erzeugte 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>

10voto

Turker Tunali Punkte 327

"Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei zum Speichern von Konfigurationseinstellungen verwenden sollte?" Nein, nicht unbedingt. Wir verwenden SharpConfig für solche Vorgänge.

Wenn eine Konfigurationsdatei zum Beispiel so aussieht

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

Wir können Werte wie folgt 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

8voto

gatapia Punkte 3392

Mir gefällt die vorgeschlagene Lösung nicht, nämlich die Verwendung von web.config o app.config . Versuchen Sie, Ihr eigenes XML zu lesen. Werfen Sie einen Blick auf XML-Einstellungsdateien - Keine web.config mehr .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X