Frage

Ich habe ein kleines Programm geschrieben, das mir die Datei App.config ein einfaches AppSetting für eine andere Anwendung ändern kann, und speichern Sie die Änderungen:

 //save a backup copy first.
 var cfg = ConfigurationManager.OpenExeConfiguration(pathToExeFile);
 cfg.SaveAs(cfg.FilePath + "." + DateTime.Now.ToFileTime() + ".bak"); 

 //reopen the original config again and update it.
 cfg = ConfigurationManager.OpenExeConfiguration(pathToExeFile);
 var setting = cfg.AppSettings.Settings[keyName];
 setting.Value = newValue;

 //save the changed configuration.
 cfg.Save(ConfigurationSaveMode.Full); 

Das funktioniert gut, bis auf einen Nebeneffekt. Das neu gespeicherte Datei .config verliert alle ursprünglichen XML-Kommentare, aber nur innerhalb des AppSettings Bereichs. Ist es möglich, XML-Kommentare aus dem ursprünglichen Konfigurationsdatei AppSettings Bereich zu behalten?

Hier ist ein Pastebin der vollständigen Quelle, wenn Sie möchten, um schnell kompilieren und ausführen.

War es hilfreich?

Lösung

Ich sprang in Reflector.Net und schaute auf die dekompiliert Quelle für diese Klasse. Die kurze Antwort ist nein, es wird nicht die Kommentare behalten. Die Art und Weise Microsoft die Klasse geschrieben hat, ist ein XML-Dokument aus den Eigenschaften auf der Konfigurationsklasse zu erzeugen. Da die Kommentare in der Konfigurationsklasse nicht auftauchen, sie es nicht in die XML machen zurück.

Und was macht das schlimmer ist, dass Microsoft alle diese Klassen versiegelt, so dass Sie nicht eine neue Klasse ableiten können und eine eigene Implementierung einfügen. Ihre einzige Möglichkeit ist, um die Kommentare außerhalb der AppSettings Abschnitts oder Verwendung XmlDocument oder XDocument Klassen zu bewegen, anstatt die Config-Dateien zu analysieren.

Es tut uns leid. Dies ist ein Grenzfall, dass Microsoft einfach nicht planen.

Andere Tipps

Hier ist eine Beispielfunktion, dass Sie die Kommentare zu speichern verwenden, um könnten. Es ermöglicht Ihnen, bearbeiten einen Schlüssel / Wert-Paar zu einer Zeit. Ich habe auch ein paar Sachen zu formatieren Sie die Datei schön auf der Grundlage der Art und Weise habe ich die Dateien häufig verwenden (Sie könnten leicht entfernen, wenn Sie möchten). Ich hoffe, diese helfen könnte jemand anderes in der Zukunft.

public static bool setConfigValue(Configuration config, string key, string val, out string errorMsg) {
    try {
        errorMsg = null;
        string filename = config.FilePath;

        //Load the config file as an XDocument
        XDocument document = XDocument.Load(filename, LoadOptions.PreserveWhitespace);
        if(document.Root == null) {
            errorMsg = "Document was null for XDocument load.";
            return false;
        }
        XElement appSettings = document.Root.Element("appSettings");
        if(appSettings == null) {
            appSettings = new XElement("appSettings");
            document.Root.Add(appSettings);
        }
        XElement appSetting = appSettings.Elements("add").FirstOrDefault(x => x.Attribute("key").Value == key);
        if (appSetting == null) {
            //Create the new appSetting
            appSettings.Add(new XElement("add", new XAttribute("key", key), new XAttribute("value", val)));
        }
        else {
            //Update the current appSetting
            appSetting.Attribute("value").Value = val;
        }


        //Format the appSetting section
        XNode lastElement = null;
        foreach(var elm in appSettings.DescendantNodes()) {
            if(elm.NodeType == System.Xml.XmlNodeType.Text) {
                if(lastElement?.NodeType == System.Xml.XmlNodeType.Element && elm.NextNode?.NodeType == System.Xml.XmlNodeType.Comment) {
                    //Any time the last node was an element and the next is a comment add two new lines.
                    ((XText)elm).Value = "\n\n\t\t";
                }
                else {
                    ((XText)elm).Value = "\n\t\t";
                }
            }
            lastElement = elm;
        }

        //Make sure the end tag for appSettings is on a new line.
        var lastNode = appSettings.DescendantNodes().Last();
        if (lastNode.NodeType == System.Xml.XmlNodeType.Text) {
            ((XText)lastNode).Value = "\n\t";
        }
        else {
            appSettings.Add(new XText("\n\t"));
        }

        //Save the changes to the config file.
        document.Save(filename, SaveOptions.DisableFormatting);
        return true;
    }
    catch (Exception ex) {
        errorMsg = "There was an exception while trying to update the config value for '" + key + "' with value '" + val + "' : " + ex.ToString();
        return false;
    }
}

Wenn Kommentare kritisch sind, könnte es nur sein, dass die einzige Möglichkeit ist, um die Datei manuell zu lesen und speichern (via XmlDocument oder die neuen Linq-ähnliche API). Wenn jedoch diese Kommentare nicht kritisch sind, würde ich entweder sie gehen lassen oder vielleicht betrachten sie als (wenn auch redundant) Datenelemente eingebettet werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top