Search code examples
c#configurationinterprocess

C#: Read and modify settings in another application's app.config file


I have a number of applications running which communicate with each other but none of these applications have their own user interface. I have a system console application which acts as a user interface for the system (i.e. the set of applications which all talk to each other).

I would like to be able to use the system console to read and modify the configuration of each of the non-gui apps.
Each app has an app.config file created using the Visual Studio Settings GUI. The settings are all in application scope, which results in an app.config file which looks a bit like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="ExternalConfigReceiver.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
</configSections>
<applicationSettings>
    <ExternalConfigReceiver.Properties.Settings>
        <setting name="Conf1" serializeAs="String">
            <value>3</value>
        </setting>
        <setting name="Conf2" serializeAs="String">
            <value>4</value>
        </setting>
    </ExternalConfigReceiver.Properties.Settings>
</applicationSettings>

I have tried using the following code to read the configuration settings:

System.Configuration.ExeConfigurationFileMap fileMap = new   System.Configuration.ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "PATH_TO_THE_FOLDER\\app.config";

System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(fileMap, System.Configuration.ConfigurationUserLevel.None);

someVariable =  config.AppSettings.Settings["Conf1"];
someVariable2 = config.AppSettings.Settings["Conf2"];

However on closer inspection of the config.AppSettings object, I find that it contains no settings.

What am I doing wrong? Am I using the wrong method to read the config file? Is this method best for a different sort of config file?


Solution

  • Its possible to use the config file as XML and then use XPath to change values:

    using (TransactionScope transactionScope = new TransactionScope())
    {
        XmlDocument configFile = new XmlDocument();
    
        configFile.Load("PathToConfigFile");
    
        XPathNavigator fileNavigator = configFile.CreateNavigator();
    
        // User recursive function to get to the correct node and set the value
        WriteValueToConfigFile(fileNavigator, pathToValue, newValue);
    
        configFile.Save("PathToConfigFile");
    
        // Commit transaction
        transactionScope.Complete();
    }
    
    private void WriteValueToConfigFile(XPathNavigator fileNavigator, string remainingPath, string newValue)
    {
        string[] splittedXPath = remainingPath.Split(new[] { '/' }, 2);
        if (splittedXPath.Length == 0 || String.IsNullOrEmpty(remainingPath))
        {
            throw new Exception("Path incorrect.");
        }
    
        string xPathPart = splittedXPath[0];
        XPathNavigator nodeNavigator = fileNavigator.SelectSingleNode(xPathPart);
    
        if (splittedXPath.Length > 1)
        {
            // Recursion
            WriteValueToConfigFile(nodeNavigator, splittedXPath[1], newValue);
        }
        else
        {
            nodeNavigator.SetValue(newValue ?? String.Empty);
        }
    }
    

    Possible path to Conf1:

    "configuration/applicationSettings/ExternalConfigReceiver.Properties.Settings/setting[name=\"Conf1\"]/value"