c# – .NET 2.0 – Anwendungseinstellungen im Bereich Anwendung – Schreibgeschütz

Auch wenn wir uns im Zeitalter von NET Framework 3.5 befinden ist dieser Beitrag in der Überschrift mit .NET 2.0 beschrieben, da sich in an dem Konzept der Anwendungseinstellungen seit .NET 2.0 keine Änderungen ergeben haben.

Mit dem Konzept der Anwendungseinstellungen wurde ein mehr oder weniger durchgängiges Konzept zur Speicherung und Verwendung von Anwendungs- und Benutzerspezifischen Daten eingeführt.

Bei der Einstellungen für eine Anwendung wird dabei zwischen zwei Bereichen (Benutzer / Anwendung) unterschieden.

Im Bereich Benutzer können die Einstellungen aus dem Programmcode sowohl gelesen als auch geschrieben werden.

Beispiel (Überprüfen ob eine Einstellung korrekt ist, wenn nicht dann aktualisieren und speichern):

// Lagereinheit Report
reportName = Settings.Default.Lagereinheit_ReportName;
if (!File.Exists(reportName))
{
    string tempName = File.GetFilenName(reportName);
    tempName = Application.StartupPath + "\\Reports\\" + tempName;
    if (File.Exists(tempName))
    {
        Settings.Default.Lagereinheit_ReportName = tempName;
        Settings.Default.Save();
    }
}

Im Bereich Anwendung können die Einstellungen aus dem Programmcode lediglich gelesen werden (Schreibgeschützt), der obige Programmcode würde also einen Fehler erzeugen, da die Anwendungseinstellungen Schreibgeschützt sind.

Was aber, wenn man eine Einstellung die als Anwendungseinstellung definiert ist, durch Programmcode ändern und in die Config Datei zurückschreiben muss.

Dann kann man dazu folgende statische Methode verwenden:

private static void setAppSetting(string SettingdName, string SettingValue)
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.PreserveWhitespace = true;
    xmlDoc.Load(config.FilePath.Trim());
    XmlNode appSettingNode = xmlDoc.SelectSingleNode("configuration/applicationSettings");
    XmlNode settingNode = appSettingNode.SelectSingleNode(string.Format("//setting[@name='{0}']", SettingdName));
    XmlNode valueNode = settingNode.SelectSingleNode("value");
    valueNode.InnerText = SettingValue;
    xmlDoc.Save(config.FilePath.Trim());
}

Nachfolgend ein Beispiel wie man diese Methode im Programmcode einsetzt um eine “normerweise Schreibgeschütze” Einstellung zu ändern.

// auf normalem Weg lesend auf die Anwendungseinstellung zugreifen
if (Properties.Settings.Default.ApplicationVerladestelle == "DDC") 
{
	// Und hier mit Hilfe der setAppSetting Methode einen neuen Wert zuweisen und in die config Datei schreiben
    setAppSetting("ApplicationVerladestelle", "DCW");  
}

Settings.Default.Reload();  // Nicht vergessen, die aktuellen Werte noch mal zu laden

7 Gedanken zu „c# – .NET 2.0 – Anwendungseinstellungen im Bereich Anwendung – Schreibgeschütz“

  1. Dabei sollte beachtet werden, das eine Anwendung in der Regel unter "Programme" oder "Program files" liegt und man ohne Admin Rechte auf die App.Config und somit auf die Einstellungen die im Bereich "Anwendung" geändert werden, keinen Schreibzugriff hat.

  2. Da hast du absolut recht, Schreibrechte in dieser Verzeichnisstruktur sind dazu notwendig.
    Ich habe damit aber selbst in großen (sehr großen) Organisationen keine Probleme, da die Benutzer lokal dort lokale Administrationsrechte haben. In mittleren und kleineren Betrieben sieht häufig aber auch anders aus. Aber gut das hat mit dem Faktum nichts zu tun.
    Vielen Dank für deinen Hinweis..

  3. Hallo,

    vielen Dank für dein super Beispiel!

    Hast du evtl. eine Idee wie ich diese nicht nur auf Strings sondern auch auf eine
    StringCollection anwenden kann?

    Vielen Dank für deine Antwort
    Grüße

  4. Hallo nochmals,

    also ich habe das Problem, das ich einen Windows Service geschriben habe.
    Diesen kann ich über Startparamter steuern.
    Service.exe -i // installiert den Service
    Service.exe -u // deinstalliert den Service
    Service.exe -g // startet eine Windows Form

    Mit der Windows Form möchte ich Einstellungen machen. Dies habe ich weil es C# über die Propeties (Settings.settings)
    realisiert. Hier kommt nun das Problem, das ich die Properties lesen und auch schreiben kann, allerdings werdend die
    geänderten Properties in der User.config im User Verzeichnis gespeichert.

    Diese bringt mir für meinen Service nichts, da dieser ja nicht von einem User ausgeführt wird sondern vom Service Manager von Windows gestartet wird.

    Nun bin ich auf der Suche wie ich meine Änderungen, welche ich über das Windows From (GUI) mache in der app.config speichern kann, damit der Service auch diese verwendet.

    Mit einfachen Properties welche den Type String haben funktioniert dies bereits. Allerdings habe ich auch Properties,
    welche den Type StringCollection haben. Und genau diese würde ich auch gerne über die GUI ändern und anschließend
    in die app.config bzw. MeinService.exe.config speichern.

    Soweit ich das verstanden habe macht dein obiger Code genau dies, jedoch nur für den Datentype String.

    Hoffe dies hilft ein wenig weiter und mein Problem zu verstehen.
    Für ein Lösung wäre ich dankbar, da ich das erste mal mit C# programmiere.
    Ich komme normalerweise aus der C++ Welt 🙂

    Grüße
    Pascal

  5. Hallo Pascal,
    ich verwende in Services meistens nicht die Anwendungseinstellungen, sondern speichere mir meine Konfiguration in einem AppSettings Abschnitt der config Datei.
    Dazu verwende ich ein Code Konstrukt wie der hier nachfolgende:

    Hier ein Beispiel
    #region property MailQueueFolder
    private static string mailQueueFolder;
    public static string MailQueueFolder
    {
    get
    {
    if (mailQueueFolder == null)
    {
    try
    {
    string setting = ConfigurationManager.AppSettings["MailQueueFolder"];
    if (setting != null)
    {
    mailQueueFolder = setting;
    }
    else // Gibt es noch nicht, Default Eintrag erstellen
    {
    string currentDir = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string newDir = Path.getPath(currentDir) + @"MailQueue\";
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    config.AppSettings.Settings.Add("MailQueueFolder", newDir);
    config.Save(ConfigurationSaveMode.Modified);
    mailQueueFolder = newDir;
    }
    mailQueueFolder = Path.getPath(mailQueueFolder);
    if (!File.Exists(mailQueueFolder))
    {
    Directory.CreateDirectory(mailQueueFolder);
    }
    }
    catch (Exception ex)
    {
    string message = Exceptions.Exceptions.createExceptionMessage(ex);
    EventLog.WriteEntry("Property – MailQueueFolder", message, EventLogEntryType.Error);
    return "";
    }
    }
    return mailQueueFolder;
    }
    }
    #endregion

    Hierdurch habe ich einfachen Zugriff auf die Konfiguration, und habe die volle Kontrolle über den Zugriff, so kann ich zum Beispiel auch eine String Collection speichern indem ich die String Collection in einen String umwandle der den String der Collection mit einem Trennner ";" Semikolon oder "," Komman trennt, also so:
    Zeile 1;Zeile 2; Zeile 3 usw.
    Diese lese ich dann als String ein konvertiere diese wieder in ein string [] mit String.Splitt(";").

    Hoffe das hilft

    Beste Grüße
    HP

  6. Hallo Hans-Peter,

    Habe es nun ein bisschen anderst gelöst, und zwar in dem ich mir
    selbst Section-, Element- und ElementCollections- Klassen erstellt habe.
    Diese kann ich selbst so gestalten wie sie mir gefallen.
    Auch der Zugriff gestaltet sich dann relativ einfach.

    Trotzdem vielen vielen Dank für deine Mühe und Hilfe!

    Viele Grüße
    Pascal

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.