vs2022 desktop - how to write/read runtime settings?

Rhodan

Well-known member
Joined
Apr 7, 2015
Messages
52
Programming Experience
10+
For some reason my last project had no problems setting and reading things in my config file (appname.exe.config) but for some reason in a new app I can write to the file but never read anything but blanks. Here's what I am doing. The config file automagically appears in the debug folder (I didn't add new to get one).

I have "using System.Configuration" in the header.

The class starts this way:

utills class:
    public static class Utils
    {
        public static bool SaveKeyValue(string key, string value)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

            config.AppSettings.Settings.Remove(key);
            config.AppSettings.Settings.Add(key, value);

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
            return true;
        }
        public static string GetKeyValue(string sKey)
        {
            MessageBox.Show("Key: " + sKey);
            string value = ConfigurationManager.AppSettings[sKey];
            return value;
        }

I checked and the sKey value is exactly the same in both the save and get functions (I use a single constant to send to both so I shouldn't even have had to check but what the heck.) The setting shows up in the <appname>.exe.config file

XML:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <appSettings>
        <add key="dbLocation" value="C:\ProgramData\PatPOS\PatPOS.sqlite3" />
    </appSettings>
</configuration>

but when I read dbLocation I get nothing. I must be missing something in this app (though I copied the code from a working app so it shouldn't be).

If no ideas then is there some other way of setting an application scope variable during runtime and being able to read/change it later? the MS settings works fine on a user scope but is read only on an application scope so that's no good to me.
 
Solution
You can use VS2022. Just pick the "Windows Forms (.NET Framework)" project instead of the "Windows Forms".

Like in my example above, I was using .NET Framework 4.8.1 which is the latest supported version, but at the same time still in the old branch of the family rather than the .NET Core branch.
Well I created a much simpler app to do the same thing. One form, two buttons, nothing else. I changed from passing around the key name to just hard coding it and using cut and paste to eliminate any possibility of a spelling or case difference between the write and the read. Still same thing - the config file shows the setting but all I get back is a blank.


C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;

namespace ConfigTest
{
    public partial class frmStart : Form
    {
        public frmStart()
        {
            InitializeComponent();
        }

        private void btnSet_Click(object sender, EventArgs e)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

            config.AppSettings.Settings.Remove("dbLocation");
            config.AppSettings.Settings.Add("dbLocation", "There");

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");

        }

        private void btnGet_Click(object sender, EventArgs e)
        {
            string value = ConfigurationManager.AppSettings["dbLocation"];
            MessageBox.Show(value);

        }
    }
}
 
Works fine for me (running using .NET Framework 4.8.1:
C#:
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Configuration;

namespace WinForms
{
    class MainForm : Form
    {
        MainForm()
        {
            var flow = new FlowLayoutPanel() { Dock = DockStyle.Fill };

            var btnSave = new Button()
            {
                Text = "Save",
                AutoSize = true,
                AutoSizeMode = AutoSizeMode.GrowAndShrink
            };
            btnSave.Click += BtnSave_Click;

            var btnLoad = new Button()
            {
                Text = "Load",
                AutoSize = true,
                AutoSizeMode = AutoSizeMode.GrowAndShrink
            };
            btnLoad.Click += BtnLoad_Click;

            SuspendLayout();
            flow.SuspendLayout();
            Controls.Add(flow);
            flow.Controls.Add(btnSave);
            flow.Controls.Add(btnLoad);
            flow.ResumeLayout(true);
            ResumeLayout(true);
        }

        void BtnSave_Click(object sender, EventArgs e)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

            config.AppSettings.Settings.Remove("dbLocation");
            config.AppSettings.Settings.Add("dbLocation", DateTime.Now.ToString());

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }

        void BtnLoad_Click(object sender, EventArgs e)
        {
            string value = ConfigurationManager.AppSettings["dbLocation"];
            MessageBox.Show(value);
        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}


1725566949789.png
 
The problem reproduces when using .NET 8.0. If you are using .NET 8.0 you should not be using app.exe.config. You should be using appsettings.json.

Anyway, I suspect that if you dig through the .NET 8.0 documentation, it likely states something about ConfigurationManager not working properly in .NET 8.0.
 
Your code looks almost identical to mine but for some reason mine doesn't work (.net 8). Must be a bug in vstudio. I will create a new simple app in vs2022 and copy ALL of your code to it and see if it works. If not then I'll try vs2019... if not then I am totally clueless about what to do.
 
The problem reproduces when using .NET 8.0. If you are using .NET 8.0 you should not be using app.exe.config. You should be using appsettings.json.

Anyway, I suspect that if you dig through the .NET 8.0 documentation, it likely states something about ConfigurationManager not working properly in .NET 8.0.

Ahhhaahhh! Ok, I will look into how to use the json settings then. Thanks a bunch!
 
Workaround is not to use the helper static class...
C#:
        void BtnLoad_Click(object sender, EventArgs e)
        {
#if NETFRAMEWORK
            string value = ConfigurationManager.AppSettings["dbLocation"];
#else
            Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
            string value = config.AppSettings.Settings["dbLocation"].Value;
#endif
            MessageBox.Show(value);
        }
 
Must be a bug in vstudio.

Not a bug in Visual Studio. Visual Studio is just the IDE. It plays no role when your code is running. The bug is in the port of the ConfigurationManager class to .NET from .NET Framework. I haven't tried it yet, but I have a sneaking suspicion that the port was optimized and only tested for use in ASP.NET, but not for desktop apps.
 
Well I think you are correct and that .net8 app.config doesn't work properly any more. I got as far as a routine to READ an appsettings.json file but cannot find any way to create one. I'm under the impression that there should be an item in the "add new" requester called something like App Settings file but I cannot find anything. Where is a starter file (or how do you create in code?
 
The link is for WPF but most of it is still applicable to WinForms.

As an aside, if you are writing new code, you really shouldn't be using WinForms. WinForms was originally going to be abandoned, but Microsoft was forced to port it into .NET Core 3.0 and up because a lot of businesses were complaining that at first MS told people to use WinForms and so the did, and now they have a lot of legacy line-of-business WinForms apps that they need to maintain.
 
I tried wpf several times in the past and I honestly hate the system. The application I'm trying to write is for only my use and since it is all for me then I get the windows system that I like.

As far as I can tell the appsettings.json file is only available for ASP programs (web programming) which I am not doing (intentionally in this case). Looks like I will have to use a much older version of visual studio/.net. Maybe 4.5 or something.
 
You can use VS2022. Just pick the "Windows Forms (.NET Framework)" project instead of the "Windows Forms".

Like in my example above, I was using .NET Framework 4.8.1 which is the latest supported version, but at the same time still in the old branch of the family rather than the .NET Core branch.
 
Solution
Ahhha! That solved my problems entirely. Now I can use the simple appsettings.cfg without issues. I saw there were TWO entries for create a .net project but couldn't see any differences. The first project that worked fine was probably this version and the second where it didn't work was probably the other version. They REALLY need to add descriptions so you can tell then are different.

Thank you VERY much!
 
Back
Top Bottom