2

This is a desktop application created with .NET Framework in Windows Forms.

I want to create a way to overwrite app.config->appSettings values.

When the project init it calls a function that get params from a database matching appName.

This is the function:

    private void LoadAppConfigs()
    {
        var appConfigs = Connection.GetAppConfigs();
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

        foreach (var c in appConfigs)
        {
            config.AppSettings.Settings[c.Key].Value = c.Value;
        }

        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
    }

It works, but this implies writing to disk (modifying app.config) which is problematic because users doesn't have access to write to the disk.

Is there a way to modify AppSettings at runtime without writing to disk?

Is there another way I can use to achieve this?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Joe
  • 35
  • 6
  • Does it have to be from the appsettings itself? Couldn't you just store the information from the original appsetting in a field of your class and manipulate the field without touching your appsettings-file? – Link Jul 24 '20 at 19:47
  • 1
    [How to set app settings without save in c#](https://stackoverflow.com/questions/46191584/how-to-set-app-settings-without-save-in-c-sharp) suggests `config.AppSettings.Set(c.Key, c.Value);`. – dxiv Jul 24 '20 at 19:57
  • Thank you to @dxiv to comment the answer. [How to set app settings without save in c#](https://stackoverflow.com/questions/46191584/how-to-set-app-settings-without-save-in-c-sharp) – Joe Jul 25 '20 at 15:21

1 Answers1

1

Based on my research, I find two ways to modify the appsettings at runtime.

First, you can use XmlDocument to change it. As follows:

            XmlDocument xml = new XmlDocument();
            string basePath = Directory.GetParent(Environment.CurrentDirectory).Parent.FullName;
            string path = basePath + @"\App.config";
            xml.Load(path);
            XmlNode xNode;
            XmlElement xElem1;
            XmlElement xElem2;            
            Configuration cfa = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            xNode = xml.SelectSingleNode("//appSettings");
            string AppKey = "Setting2";
            string AppValue = "Expensive";
            xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@key='" + AppKey + "']");
            if (xElem1 != null)
            {
                xElem1.SetAttribute("value", AppValue);
                cfa.AppSettings.Settings[AppKey].Value = AppValue;
            }
            else
            {
                xElem2 = xml.CreateElement("add");
                xElem2.SetAttribute("key", AppKey);
                xElem2.SetAttribute("value", AppValue);
                xNode.AppendChild(xElem2);
                cfa.AppSettings.Settings.Add(AppKey, AppValue);
            }
            cfa.Save();
            ConfigurationManager.RefreshSection("appSettings");
            xml.Save(path);

Second, you can also use config.AppSettings.Settings[key].Value =value;. Code:

    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    config.AppSettings.Settings["Setting2"].Value = "Expensive";
    config.Save();//exe.config change
    string basePath = Directory.GetParent(Environment.CurrentDirectory).Parent.FullName;
    string path = basePath + @"\App.config";
    config.SaveAs(path);//App.config change
    ConfigurationManager.RefreshSection("appSettings");

Last but not least, you can refer to How do I force my .NET application to run as administrator? to know how to solve user permission problem.

Jack J Jun
  • 5,633
  • 1
  • 9
  • 27