Using the ConfigurationManager

I wrote the following code to get ConfigurationManager data to update it:

private static void UpdateConfigurationFile()
{
#if DEBUG
    string applicationName =
        Environment.GetCommandLineArgs()[0];
#else 
   string applicationName =
  Environment.GetCommandLineArgs()[0]+ ".exe";
#endif

    string exePath = System.IO.Path.Combine(
        Environment.CurrentDirectory, applicationName);

    // Get the configuration file. The file name has 
    // this format appname.exe.config.
    System.Configuration.Configuration config =
      ConfigurationManager.OpenExeConfiguration(exePath);

    string server = ConfigurationManager.AppSettings["server"];
}

      

At the end of the code, the server is null.

XML has the corresponding server code:

<applicationSettings>
    <forLiDAR.Properties.Settings>
        <setting name="Server" serializeAs="String">
            <value>localhost</value>
        </setting>

      

What am I doing wrong?

+3


source to share


1 answer


Ok, I have a solution to your problem.

Not easy to explain as it is not your fault, VS has a bug that has been pulling with it for years.

So let's go step by step:

  • Adding settings by right clicking on the project and going to the settings tab is not the right path for later use. That's why:

If we follow the documentation , all we have to do is:

Properties.Settings.Default.Server = "Now I'm something different than localhost";
Properties.Settings.Default.Save();

      

No need for OpenExeConfigration or whatever, just these two lines! and .NET, like a charm, should be able to store the new setting in the config file .. except it isn't :) Instead, it screams "The config system could not initialize" !!

So we think, "Okay, they didn't cover it all in the documentation .. let's add what we think is missing." And so we add:

var exePath = System.IO.Path.Combine(Environment.CurrentDirectory, "ConsoleApplication58.vshost.exe.config");
var config = ConfigurationManager.OpenExeConfiguration(exePath);
var oldSetting = config.AppSettings.Settings["Server"].Value;

      

And we'll get ... another exception - a null reference this time. So we ask, "What's going on there ?!" and from debug we add a clock for "config.AppSettings.Settings" and to our horror we see that .NET is actually trying to tell us "no spoon". (or number of settings 0)

So at this point we can conclude that this shit definitely doesn't work with an app using AppConfig .. but it might work with apps using WebConfig - I haven't tested this. (oh, just to understand, "This shit" means adding a settings file by right-clicking on the project menu and going to the settings tab)

  1. Ok ... try another method to do what adds a settings file from the Add New Item menu, its default name will be "settings1.settings" and it will be in the project's shared folder name, not properties as before.


So I did that too and tested the following lines:

var oldSetting = Settings1.Default.Server;
Settings1.Default.Server = "localhost2";
Settings1.Default.Save();

      

It worked - but I have to tell you that "Scope" should be a "user", not an "Application". If in his "application" the parameter does not have a setter .. and where did he save the information? in the AppData folder for this user. This is logical.

This, of course, means that to manually check when debugging the saved file, you need to navigate to your application's configuration file, which is in the AppData folder, not the debug / bin folder.

  1. But all of this, of course, is not what you asked ... Since you want to keep the application area setting, right? Well .. you can't ... they weren't meant to be. You can read it here: https://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx

ApplicationSettings class does not support saving settings file app.config. This is very design, applications that work with (think Vista UAC) do not have write access to the program's installation folder.

You can fight the system using the ConfigurationManager class. But a trivial workaround is to go into Customizer and change the realm setting for the user. If this is difficult (say, customization specific to each user), you must add the "Options" function to a separate program so that you can request a privilege refund request. Or opt out using the setting.

So, for the last time, I'll try to show you what your application should look like:

namespace ConsoleApplication58
{
    class Program
    {
        static void Main(string[] args)
        {
            UpdateConfigurationFile();
        }

        private static void UpdateConfigurationFile()
        {
            var oldSetting = Settings1.Default.Server; //to get the current setting if you want..
            Settings1.Default.Server = "localhost2"; //to change the setting.
            Settings1.Default.Save(); //to save settings.
        }
    }
}

      

And if you add the Settings1.Settings file as I mentioned, this is how appConfig looks like:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ConsoleApplication58.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
    </startup>

    <userSettings>
        <ConsoleApplication58.Settings1>
            <setting name="Server" serializeAs="String">
                <value>localhost</value>
            </setting>
        </ConsoleApplication58.Settings1>
    </userSettings>
</configuration>

      


As requested in the comment, here's a link to the bug report:
Configuration in App.Config and ApplicationSettings

+1


source







All Articles