Reputation:
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
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
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