user3518663
user3518663

Reputation:

Edit a .config file of another executable

I need to edit the configuration file (exefilename.config) of an executable that is not the one from which the code runs. The XML file format is this:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="XNet.XNetService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
        <section name="XNetService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
</configSections>
<applicationSettings>
    <XNet.XNetService.Properties.Settings>
        <setting name="DataSource" serializeAs="String">
            <value>192.168.2.127</value>
        </setting>
        <setting name="DefaultPort" serializeAs="String">
            <value>8085</value>
        </setting>
        <setting name="UserName" serializeAs="String">
            <value>notiuser</value>
        </setting>
        <setting name="Password" serializeAs="String">
            <value>6ITLet6k1HCOhgTmXI5C/1m1DrCQli8dIAKfdtP+o6w=</value>
        </setting>
        <setting name="Instance" serializeAs="String">
            <value />
        </setting>
        <setting name="bindTo" serializeAs="String">
            <value />
        </setting>
    </XNet.XNetService.Properties.Settings>
</applicationSettings>

I need to change the "DefaultPort" parameters, "DataSource" etc .. and adding new ones at the same level. How can I do? If the .config file was that of my executable, the situation would be much easier with a simple SettingsWriter, but in this case how can I do?

Upvotes: 0

Views: 295

Answers (2)

user3518663
user3518663

Reputation:

I implement the code descripted in this thread: Change default app.config at runtime as suggested by Alex Nolasco.

But when I try to read the property "Datasource" like descripted below, I still get the original .config value :-(

// the default app.config is used.
using (AppConfig.Change(exePath))
{
    // the app.config in exePath is used

    string test = Properties.Settings.Default.DataSource;

}
// the default app.config is used.

I have a doubt: the temporary configuration file that I'm going to read has got a different assemby. Can this be the problem?

This is the AppConfig code:

using System;
using System.Configuration;
using System.Linq;
using System.Reflection;

namespace XNet.XManager
{
    public abstract class AppConfig : IDisposable
    {
        public static AppConfig Change(string path)
        {
            return new ChangeAppConfig(path);
        }

        public abstract void Dispose();

        private class ChangeAppConfig : AppConfig
        {
            private readonly string oldConfig = AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();

            private bool disposedValue;

            public ChangeAppConfig(string path)
            {
                AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
                ResetConfigMechanism();
            }

            public override void Dispose()
            {
                if (!disposedValue)
                {
                    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);
                    ResetConfigMechanism();


                    disposedValue = true;
                }
                GC.SuppressFinalize(this);
            }

            private static void ResetConfigMechanism()
            {
                typeof(ConfigurationManager)
                    .GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, 0);

                typeof(ConfigurationManager)
                    .GetField("s_configSystem", BindingFlags.NonPublic |BindingFlags.Static)
                    .SetValue(null, null);

                typeof(ConfigurationManager)
                    .Assembly.GetTypes()
                    .Where(x => x.FullName ==
                                "System.Configuration.ClientConfigPaths")
                    .First()
                    .GetField("s_current", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, null);
            }
        }
    }
}

Upvotes: 0

parvee
parvee

Reputation: 98

Web config is just an XML, so why not just treat it as one? Something along these lines should do the trick:

    void ModifyConfig(string filepath, string xpath, string newValue)
    {
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(filepath);
        System.Xml.XmlNode elementToReplace = doc.DocumentElement.SelectSingleNode(xpath);
        elementToReplace.InnerText = newValue;
        doc.Save(filepath);
    }

and call it like:

        ModifyConfig("C:\\temp\\App.config", 
           "applicationSettings//XNet.XNetService.Properties.Settings//setting[@name='DefaultPort']//value",
            "5000");

You might get a problem if the file is in use though.

Upvotes: 1

Related Questions