Saturday, August 14, 2010

C#: HowTo directly change a setting in an "*.exe.config" file

I had been searching for more than half a day for a way to directly change the values in the appSettings section in the  *.exe.config of my application. The problem is that the settings are read-only. I found no way to write to the *.exe.config file. I neither found a class or a method online to do this.
So I created my own method which directly accesses the *.exe.config file by making use of its XML structure.
Thus, I am able to add and change nodes and ultimately save the XML file.

Here is the code:


using System.Xml;
public void SaveSettingsToConfigFile(string settingSection, string settingName, object settingValue)
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config");

    // Find settings node in the xml file. Create of not available
    XmlNode SettingsNode = xmlDoc.SelectSingleNode("//configuration/" + settingSection);
    if (SettingsNode == null)
    {
        // Create new settings node
        SettingsNode = xmlDoc.CreateElement(settingSection);

        // Get "configuration" node
        XmlNode configurationNode = xmlDoc.SelectSingleNode("//configuration");
        if (configurationNode == null)
        {
            // not found => create
            configurationNode = xmlDoc.CreateElement("configuration");
            xmlDoc.AppendChild(configurationNode);

        }
        //Find configSections node
        XmlNode configSectionsNode = xmlDoc.SelectSingleNode("//configuration/configSections");
        if (configSectionsNode == null)
        {
            // not found => create
            configSectionsNode = xmlDoc.CreateElement("configSections");
            configurationNode.AppendChild(configSectionsNode);
        }

        //Find section node
        XmlNode sectionNode = xmlDoc.SelectSingleNode("//configuration/configSections/section[attribute::name='" + settingSection + "']");
        if (sectionNode == null)
        {
            // not found => create
            XmlElement sectionElement = xmlDoc.CreateElement("section");
            sectionElement.SetAttribute("name", settingSection.ToString());
            sectionElement.SetAttribute("type", "System.Configuration.NameValueSectionHandler");

            configSectionsNode.AppendChild(sectionElement);
        }

        //Append Settings node to configurationNode
        configurationNode.AppendChild(SettingsNode);
    }

    //Find add node
    XmlNode addNode = xmlDoc.SelectSingleNode("//configuration/" + settingSection + "/add[attribute::key='" + settingName + "']");

    if (addNode != null)
    {
        // found => change value
        addNode.Attributes["value"].InnerText = settingValue.ToString();
    }
    else
    {
        // not found => create
        XmlElement addElement = xmlDoc.CreateElement("add");

        // add attributes
        addElement.SetAttribute("key", settingName.ToString());
        addElement.SetAttribute("value", settingValue.ToString());

        // append settings
        SettingsNode.AppendChild(addElement);
    }
    xmlDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config");

}


-----------------------------

 UPDATE
-----------------------------
Screw the above code. The following is much easier and uses a .net built in funktionality. Found on http://msdn.microsoft.com/de-de/library/system.configuration.appsettingsreader.aspx


        static void Main(string[] args)
        {

            // Get the count of the Application Settings.
            int appStgCnt = ConfigurationManager.AppSettings.Count;

            string asName = "AppStg" + appStgCnt.ToString();

            // Get the configuration file.
            System.Configuration.Configuration config =
              ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            // Add an Application setting.
            config.AppSettings.Settings.Add(asName,
              DateTime.Now.ToLongDateString() + " " +
              DateTime.Now.ToLongTimeString());

            // Save the configuration file.
            config.Save(ConfigurationSaveMode.Modified);

            // Force a reload of a changed section.
            ConfigurationManager.RefreshSection("appSettings");


            Console.WriteLine();
            Console.WriteLine("Application Settings:");
            ShowAppSettings();
            Console.WriteLine();

            Console.WriteLine("Press 'Enter' to exit.");
            Console.ReadLine();
        }

No comments:

Post a Comment