Wie Anwendungseinstellungen in einer Windows Forms-Anwendung speichern?
-
19-08-2019 - |
Frage
Was ich erreichen will, ist sehr einfach: Ich habe eine Windows Forms (.NET 3.5) Anwendung, die zum Lesen von Informationen einen Pfad verwendet. Dieser Pfad kann vom Anwender geändert werden, indem die Optionen Formular I liefern.
Nun, ich mag für die spätere Verwendung des Pfadwert in eine Datei speichern. Dies wäre eine der vielen Einstellungen in dieser Datei gespeichert werden. Diese Datei würde sitzt direkt im Anwendungsordner.
Ich verstehe, drei Optionen stehen zur Verfügung:
- Configuration Datei (appname.exe.config)
- Registry
- Benutzerdefinierte XML-Datei
Ich habe gelesen, dass die .NET-Konfigurationsdatei nicht, um es für das Speichern von Werten zurück vorgesehen ist. Da für die Registrierung, würde Ich mag so weit weg wie möglich von ihm erhalten.
Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei verwenden soll, Konfigurationseinstellungen zu speichern? Wenn ja, ich möchte Codebeispiel dieser (C #) sehen.
Ich habe zu diesem Thema weitere Diskussionen gesehen, aber es ist mir noch nicht klar.
Lösung
Wenn Sie mit Visual Studio arbeiten, dann ist es ziemlich einfach persistierbar Einstellungen zu bekommen. Rechtsklick auf das Projekt in Projektmappen-Explorer, wählen Sie Eigenschaften. Wählen Sie die Registerkarte Einstellungen, klicken Sie auf den Hyperlink, wenn die Einstellungen nicht existiert. Verwenden Sie die Registerkarte Einstellungen Anwendungseinstellungen zu erstellen. Visual Studio erstellt die Dateien Settings.settings
und Settings.Designer.settings
, die die Singletonklasse Settings
geerbt von Application . Sie können diese Klasse aus dem Code Zugriff / Schreibanwendungseinstellungen zu lesen:
Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file
Diese Technik ist sowohl für Konsole, Windows Forms und andere Projekttypen.
Beachten Sie, dass Sie die Anwendungsbereich Eigenschaft Ihrer Einstellungen festlegen müssen. Wenn Sie Anwendungsbereich wählen dann Settings.Default.
Andere Tipps
Wenn Sie im selben Verzeichnis in eine Datei auf Speicher als ausführbare Datei planen, hier ist eine schöne Lösung, die die
Die Registrierung ist eine No-go. Sie sind nicht sicher, ob der Benutzer, die Ihre Anwendung verwendet, verfügt über ausreichende Rechte für die Registrierung zu schreiben. Sie können die Ich würde speichern benutzerspezifische Einstellungen in einer XML-Datei, die in Isolated Storage oder im SpecialFolder.ApplicationData Verzeichnis. Darüber hinaus, wie von .NET 2.0 ist es möglich, Werte zu speichern zurück in die app.config
-Datei verwenden, auf Anwendungsebene Einstellungen zu speichern (die die gleiche für jeden Benutzer sind, die Ihre Anwendung verwendet). app.config
Datei.
Die ApplicationSettings
Klasse unterstützt keine Einstellungen auf die app.config Datei zu speichern. Das ist sehr viel von Design, Apps, die mit einem ordnungsgemäß gesichert Benutzerkonto ausgeführt werden (man denke Vista UAC) keinen Schreibzugriff auf die Programminstallationsordner haben.
Sie können das System mit der ConfigurationManager
Klasse kämpfen. Aber die triviale Abhilfe ist in den Einstellungen Designer gehen und den Anwendungsbereich auf Benutzer- Einstellung ändern. Wenn das Härten verursacht (sagen wir, ist die Einstellung für jeden Benutzer relevant), sollten Sie Ihre Optionen verfügen in einem separaten Programm setzen, so dass Sie für das Privileg Anhebungsaufforderung fragen. Oder verzichten Sie eine Einstellung mit.
Die Registrierung / Configuration / XML Argument scheint immer noch sehr aktiv. Ich habe sie alle, verwendet, da die Technologie fortgeschritten ist, aber mein Favorit basiert auf Threed System mit Isolated Storage .
Das folgende Beispiel ermöglicht die Speicherung eines Objekts in eine Datei in isolierten Speichern benannte Eigenschaften. Wie zum Beispiel:
AppSettings.Save(myobject, "Prop1,Prop2", "myFile.jsn");
Eigenschaften können zurückgewonnen werden:
AppSettings.Load(myobject, "myFile.jsn");
Es ist nur ein Beispiel, nicht suggestiv bewährter Praktiken.
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) { }
}
}
}
Ich wollte eine Bibliothek teilen, die ich für diese gebaut haben. Es ist eine kleine Bibliothek, aber eine große Verbesserung (IMHO) über .settings Dateien.
Die Bibliothek heißt Jot (GitHub) , hier ist ein alter Der Code Project Artikel ich darüber geschrieben
Hier ist, wie Sie es Spur eines Fensters Größe und Lage zu halten verwenden würden:
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 wesentlich weniger Code, und es ist viel weniger fehleranfällig, da Sie nur jede Eigenschaft erwähnen müssen einmal
Mit einem Einstellungsdateien Sie müssen jede Eigenschaft erwähnen fünf Zeiten:. Einmal, wenn Sie explizit die Eigenschaft erstellen und weitere vier Mal in den Code, der kopiert die Werte hin und her
Lagerung, Serialisierung usw. sind vollständig konfigurierbar. ein [Aufspürbarer] Attribut, wenn die Zielobjekte von einem IOC-Containern erstellt werden, können Sie [es hook up] [], so dass es gilt automatisch für alle Objekte Tracking löst es so, dass alles, was Sie tun müssen, um eine Eigenschaft dauerhaft zu machen ist Slap auf sie.
Es ist in hohem Maße konfigurierbar, können Sie konfigurieren: - wenn Daten beibehalten und global oder für jedes verfolgte Objekt angewendet - wie es serialisiert - wo es gespeichert (zum Beispiel Datei, Datenbank, online, isolierte Speicher, Registry) - Regeln, die Anwendung abbrechen / Daten für eine Eigenschaft persistierenden
Vertrauen Sie mir, ist die Bibliothek erstklassig!
Eine einfache Art und Weise ist ein Konfigurationsdatenobjekt zu verwenden, ist es als XML-Datei mit dem Namen der Anwendung im lokalen Ordner speichern und beim Start zurück lesen.
Hier ist ein Beispiel, die Position und Größe eines Formulars zu speichern.
Die Konfiguration Datenobjekt ist stark typisiert und einfach zu bedienen:
[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; }
}
}
Ein 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 Ihrer Form der Last und Schließen-Ereignisse 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>
Ich mag die vorgeschlagene Lösung nicht web.config
oder app.config
zu verwenden. Versuchen Sie, Ihre eigene XML zu lesen. Werfen Sie einen Blick auf XML-Einstellungsdateien -. Nicht mehr web.config
Andere Optionen, stattdessen eine benutzerdefinierte XML-Datei zu verwenden, können wir ein benutzerfreundliche Dateiformat verwenden.
- Wenn Sie .NET 4.0 dynamische verwenden, diese Bibliothek ist wirklich einfach zu bedienen (Serialisiert, deserialize, verschachtelte Objekte unterstützen und Bestellausgangs mehrere Einstellungen zu eins) verschmelzenden JsonConfig (Nutzung entspricht Application wie Sie + möchten)
- Für .NET YAML Konfigurationsbibliothek ... Ich habe keine gefunden, die wie einfach wie JsonConfig verwenden
Sie können speichern Sie Ihre Einstellungen in mehreren speziellen Ordner-Datei (für alle Benutzer und pro Benutzer) wie hier Environment.SpecialFolder Enumeration und mehr Dateien (las Standard pro Rolle nur, pro Benutzer, etc.)
- Beispiel für den Pfad von speziellen Ordner bekommen: C # immer den Weg der % AppData%
Wenn Sie mehrere Einstellungen verwenden, können Sie diese Einstellungen zusammen: Zum Beispiel, Zusammenführen Einstellungen für Standard + BasicUser + Adminuser. Sie können Ihre eigenen Regeln verwenden. Die letzte überschreibt den Wert, etc
„Bedeutet dies, dass ich eine benutzerdefinierte XML-Datei verwenden soll, Konfigurationseinstellungen zu speichern?“ Nein, nicht unbedingt. Wir verwenden SharpConfig für solche Operationen.
Zum Beispiel, wenn config-Datei, wie das ist
[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 on the fly erstellen und wir können es später speichern. Quelle: http://sharpconfig.net/ Github: https://github.com/cemdervis/SharpConfig
Ich hoffe, es hilft.
Soweit ich das beurteilen kann, .NET unterstützt jedoch persistierende Einstellungen über die integrierte Anwendungseinstellungen Einrichtung:
Die Anwendungseinstellungen Funktion von Windows Forms macht es einfach, zu speichern, zu erstellen und benutzerdefinierte Anwendung und Benutzereinstellungen auf dem Clientcomputer erhalten. Mit dem Windows-Anwendungseinstellungen Forms können Sie speichern nicht nur Anwendungsdaten wie Datenbankverbindungszeichenfolgen, sondern auch benutzerspezifischen Daten, wie Benutzerpräferenzen Anwendung. Mit Visual Studio oder benutzerdefinierten verwalteten Code, können Sie neue Einstellungen erstellen, lesen sie aus und schreibt sie auf die Festplatte, binden sie an Eigenschaften auf Ihrer Formulare und Dateneinstellungen vor dem Laden zu validieren und zu speichern. - http://msdn.microsoft.com/en-us/library/k4s6c3a0 aspx
Manchmal wollen Sie diese Einstellungen in der traditionellen web.config oder app.config Datei gehalten loszuwerden. Sie wollen mehr feinkörnige Kontrolle über die Bereitstellung Ihrer Einstellungen Einträge und getrennte Daten Design. Oder die Anforderung ist das Hinzufügen neuer Einträge zur Laufzeit zu ermöglichen.
Ich kann zwei gute Möglichkeiten vorstellen:
- Die stark typisierte Version und
- Die objektorientierte Version.
Der Vorteil der stark typisierte Version sind die stark typisierte Einstellungen Namen und Werte. Es besteht keine Gefahr von Namen oder Datentypen Vermischungs. Der Nachteil ist, dass mehr Einstellungen codiert werden müssen, kann nicht zur Laufzeit hinzugefügt werden.
Mit der objektorientierten Version der Vorteil ist, dass neue Einstellungen zur Laufzeit hinzugefügt werden können. Aber Sie haben nicht stark typisiert Namen und Werte. Muss mit String-Bezeichner vorsichtig sein. Müssen Datentyp zuvor gespeichert haben, wann Wert zu bekommen.
Sie können den Code der beiden voll funktionsfähigen Implementierungen finden hier .
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();
}
}