How do I retrieve ApplicationSettings from a loaded App.config file?
Asked Answered
S

3

14

Is it possible to access the values from the applicationSettings section of a loaded app.config file?

I have found an example How do I retrieve appSettings, but I can't find out how to access applicationSettings this way.

Sidecar answered 20/1, 2010 at 12:25 Comment(0)
B
17

The applicationSettings are readonly during runtime. You can set/modify them either via a text editor in the app.config file directly, but it is recommended to open the project properties in Visual Studio and select the "Settings" tab. It is important to set the right scope:

  • If the settings apply to the entire application (for all users), select "Application" as scope.
  • If every user should have individual settings (bound to the user profile), then select "User"

For example, if you create myOwnSetting in your project WindowsFormsTestApplication1 as follows (change the scope to "Application"):

myOwnSetting

it will add the following to the application's app.config file:

<configuration>
    <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="WindowsFormsTestApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
    </configSections>
    <applicationSettings>
        <WindowsFormsTestApplication1.Properties.Settings>
            <setting name="myOwnSetting" serializeAs="String">
                <value>Hi there!</value>
            </setting>
        </WindowsFormsTestApplication1.Properties.Settings>
    </applicationSettings>
</configuration>

Visual Studio creates C# code to access this setting automatically (this is why you should do it in the project properties and not via text editor) - after you have saved the changes, from within the same namespace you can read its value in the application easily via the following code:

var currentValue = Properties.Settings.Default.myOwnSetting;

Given the applicationSettings in the listing above, this would retrieve the string "Hi there!" for the variable currentValue.

Note that if you have created myOwnSetting for the "User" scope, then it is stored in a section named <userSettings> instead of <applicationSettings>, but you still can access it with the code line above.

Another difference of scope "User" settings is that you have read-write access, i.e. it is allowed to do the following:

        Properties.Settings.Default.myUserSetting = "Something else";
        Properties.Settings.Default.Save();

If you try the same with the "Application" scope setting myOwnSetting, it would result in a compile-time error telling you that it is read-only.

If you re-start the application, you will notice that myUserSetting has changed to the value "Something else" - but the old value is still in the app.config. Why is this so? The reason is that it is regarded as a default value - and as I said earlier, the "User" scope is bound to the user profile. As a consequence, the value "Something else" is stored in

C:\Documents and Settings\USERID\Local Settings\Application Data\FIRMNAME\WindowsFormsTestApplicati_Url_tdq2oylz33rzq00sxhvxucu5edw2oghw\1.0.0.0

in a file named User.config, which looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <WindowsFormsTestApplication1.Properties.Settings>
            <setting name="myUserSetting" serializeAs="String">
                <value>Something else</value>
            </setting>
        </WindowsFormsTestApplication1.Properties.Settings>
    </userSettings>
</configuration>

You can't exactly tell the path as it is created automatically by the .NET Framework, and it will look different on your PC. But you can see that USERID is the Windows user ID of your current user, FIRMNAME is part of the assembly information you have specified, and the assembly name and version is also used in the path.


Note:

  • The <sectionGroup> with <section> declaration is mandatory and its name attribute needs to match with the namespace. The namespace must appear exactly once in the configuration, and there is only one applicationSettings section allowed.

  • As you could see in the config file, the namespace is mentioned explicitly there (WindowsFormsTestApplication1.Properties.Settings). As a consequence, if you want to access the settings from code not being in the same namespace you might need to use a fully qualified reference. Having said that, be careful if you copy the entire <applicationSettings>...</applicationSettings> section from one application's config to another - you might need to change the namespace in the target config afterwards.

  • If you're using the Settings Designer (Settings tab in your project), it will create a file named Settings.Settings (along with Settings.Designer.cs to access the sessings via C# code) in the Properties section of your project. This is a copy of the settings as it will be stored in your Web.config or App.config file as well (depending on your project type, only for application scope settings - user scope settings are stored based on the user profile). You can create additional *.settings files and use them (as it is described here).

  • If you're not using the settings designer, or if you're using a tool like LinqPad, you might need to use a different approach. Consider this:

      internal static string GetApplicationSetting(string key, 
              string nameSpace="Properties.Settings")
      {
          string xValue=null;
          try 
          {
              string path = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
              XDocument doc = XDocument.Load(path);
              var xPathStr= string.IsNullOrEmpty(nameSpace) 
                              ? "//applicationSettings" 
                              : $"//applicationSettings/{nameSpace}";
              var settings=doc.XPathSelectElement(xPathStr).Elements().Where(
                                  w => w.Name=="setting" 
                                      && w.HasAttributes 
                                      && w.Attribute("serializeAs").Value=="String"
                                  );
              var setting=settings.Where(f => f.HasAttributes 
                                              && f.Attribute("name").Value==key).Elements();
              xValue=setting.FirstOrDefault().Value;
          }
          catch {}
          return xValue;
      }
    

You can read string type applicationSettings by treating the configuration as an XDocument. The example given is limited to the string type and you can retrieve the setting from the app.config example above as follows:
var value=GetApplicationSetting("myOwnSetting", "WindowsFormsTestApplication1.Properties.Settings");
Likewise, you can create a similar function GetUserSetting for the default <userSettings> section: Just copy the code above, rename the function name and replace applicationSettings in the xPathStr by userSettings.

  • There is an upgrade method available for user settings, which is described here. More details about the location where user settings are stored can be found there.

  • If that implementation is too complicated for your needs, there is a second way to implement settings: The <appSettings> section in the configuration works differently, since it does not distinguish "User" and "Application" scope and it does not support different datatypes, just strings. However, it is possible to easily read and write the configuration keys/values. If you're interested in the code, you can find it here (on stackoverflow):
    how to read/write config settings of appSettings

Important:

  • If you are uncertain whether you should use appSettings or applicationSettings, then read this before you decide it. It compares both ways showing their advantages and disadvantages.
Blakeblakelee answered 14/3, 2012 at 14:56 Comment(1)
I just read your detailed answer again just after a few years have passed and realized that I had forgotten the up vote back then. Shame on me - I apologize.Sidecar
S
4

How did you create the settings? Using the VS settings designer? If so it should create you a strongly typed class for accessing them with. This is usually accessed using Properties.Settings.Default.SettingName

I think that it is preferred to use the applicationSettings rather than appSettings, but application settings are readonly at runtime, ie you cannot create them from your code, but it is possible to create and add appSettings at runtime I believe. I asked a question about the difference

you can find more information from msdn

Sow answered 20/1, 2010 at 12:34 Comment(0)
A
3
You could load the config file into XmlDocument and retrive the applicationSettings from the dom object . Here is example I found to load the config file into dom object :

//retrive the current assembly directory
private static string AssemblyDirectory()
{
        string codeBase = Assembly.GetExecutingAssembly().CodeBase;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
}



//return the value from aplicationSetting according to the given key
//appSettingSection is the your configuration section as declare in your web.config
public static string GetApplicationSettingValue(string appSettingSection,string key)
{
   //get web.config path
   string configPath  = new System.IO.DirectoryInfo(AssemblyDirectory()).Parent.FullName + "\\web.config";

    System.IO.FileInfo FileInfo = new System.IO.FileInfo(configPath);
    if (!FileInfo.Exists)
    {
        throw new Exception("Missing config file");
    }

    //load config file into xml document
    var XmlConfig = new System.Xml.XmlDocument();
    XmlConfig.Load(FileInfo.FullName);


     //override xml document and return the value of the key under applicationSettings
     foreach (System.Xml.XmlNode node in XmlConfig["configuration"]  ["applicationSettings"]appSettingSection])
     {
                    if (node.Name == "setting")
                    {
                        if (node.Attributes.GetNamedItem("name").Value == key)
                        {
                            return node.FirstChild.InnerXml.ToString();
                        }
                   }
     }
   return "";
}
Akimbo answered 16/8, 2012 at 15:45 Comment(1)
I have been looking ALL DAY for a solution that actually works. I do not have the luxury of making my config file public and accessing from other projects in WinForms. This is the way to go! :)Kluge

© 2022 - 2024 — McMap. All rights reserved.