Updating config file and updating the values in application - c#

I am currently updating a few settings in a rather large *.exe.config file via the *.exe executable by using XLinq to navigate the directories and read / write the values. The problem with updating this way is that changes only take effect after restarting the executable, but I would like the changes to take effect instantaneously. Is there a way to tell the executable to reload the *.exe.config file after I make the changes?
All help is appreciated and thanks in advance!
Exoskeleton for app.config
<configuration>
<system.serviceModel>
<!-- stuff... -->
<client>
<!-- this is the section I changed and want to have updated -->
</client>
</system.serviceModel>
</configuration>
EDIT: One of the reasons that I know so little on this subject is that I didn't create the app.config - it's auto-generated by somebody else's code. The reason that I have to change it and have the changes take effect in the application is that another part of the code (which I have no access to) calls on the config file to get its data, but if I don't reload the section then the old settings will be used, which won't work in this application.
EDIT2: If I can't change this dynamically, how do I change the code so that it can be done dynamically? Best answer gets the bounty...

var client =
System.ServiceModel.ChannelFactory<ISampleService>(
System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress)
you can connect to a service also programmatically, and give the WCF directly the config needed.
with using this, you do not need the wcf config in the exe any more.
https://msdn.microsoft.com/en-us/library/ms576132.aspx

Settings with scope "User" can be easily stored and retrieved while the Application is running. If your settings are of scope "Application" I'm afraid you cannot modify and reload them without restarting your application. You'll need to roll your own configuration solution then.

There are 2 parts to making this work. 1) Updating the correct config file, and 2) forcing .net to reload the changes.
1) When a .net process starts, it will copy the existing .config to the vshost.exe.config file. If you update the original config file after the process has started, you will not see it in the vshost.config until you restart the process. So to make this work at runtime, you need to update the vshost.exe.config, not the exe.config file.
2) To force .net to reload the settings, you need to tell the configuration manager that the settings changed. You can do this with the ConfigurationManager.RefreshSection().
There is some more information and a couple code examples at: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/3c365fdb-563e-4b0a-a4b4-df684c2dd908/

Basically, Microsoft designed it this way (having the configuration read at start up and not again), specifically to discourage you from trying this, because the *.config file live in the C:\Program Files folder, and that should not be writable by a non-Administrator.

Related

What is the correct way to modify dll.config of published project?

I published a .net core console application to my test server and scheduled it to run using task scheduler. I then wanted to turn on additional functionality using a switch from the app.config (that apparently turns into project.dll.config). The modifications did not take effect however. What is the correct way to modify my app.config file in this scenario? Do I need to republish? Maybe reschedule?
The Console Application will need to be restarted to pick up any change in its .config files.
Nope, you won't need to republish or recompile, unless you modify a ".cs" file. Just need to restart the app, like #Hayden said.

How to set up NLog configuration file load/reload when the app-config path is changed?

.Net applications are set up so that multiple instances of the same program will be (re)using the same application config (.exe.config - app.config in Visual Studio).
In our scenario we need to run each of the instances with their own .exe.config. This is not something that .Net is made to do "out of the box". However this nice little wrapper does the trick for us: https://stackoverflow.com/a/6151688/95008
This worked fine for us, until we realized that NLog does not seem to respect the app-config change. We are adding a config-section in the .exe.config for NLog which should make it possible each instance to log with different rules and targets to different locations.
But, it seems that NLog is not respecting the app-config changes. My guess is that it internally is not asking via the AppSettings API for its config-section, instead perhaps using code to manually look up the .exe.config and the config-section within it.
So, three alternatives it seems:
Look into NLog changing the code for this in a future release (given that this indeed is the issue). I will be posting an issue with the project for Update: Link to NLog issue.
Loading the configuration manually, either from the section of the .exe.config or from a specific nlog.config file (maybe given via a setting in the .exe.config). But, how do we do this effectively, so that any loggers created are based on the configs manually loaded?
Maybe there is another solution for this?
My guess is that it internally is not asking via the AppSettings API for its config-section, instead perhaps using code to manually look up the .exe.config and the config-section within it.
That's correct, as NLog is using the same code for the NLog's config, whether it's in web.config or in nlog.config
Reloading the config is easy in code, just do:
NLog.LogManager.Configuration = NLog.LogManager.Configuration.Reload();
and if there are loggers made before the config is reloaded,
NLog.LogManager.ReconfigExistingLoggers()

How I prevent to get latest or check-in a specific file automatically in Team Foundation Server?

I work on a team that works on a project. I change my project web config file to set a specific connection string but when I check-in or get latest version of project it changes to others connection strings. I have same problem in WCF Service references. appconfig and xsd files of service references always corrupted when I check-in or get latest version of program from tfs and I have to delete service references and add it again! How can I get rid of this?
We had the same issue on our project (with connection strings), and found a good solution: http://msdn.microsoft.com/en-us/library/ms254494(v=vs.110).aspx
By adding a connections.config file for each developer with his own connection string, we just needed to say that this file must not be a part of Source Control. Then in the web.config connectionString section, you just refer to the connections.config file.
Just be aware that you need to either transform your web.config or add the connections.config when publishing the site.
I know you can do the same about the appSettings section in the web.config.
How you do it with WCF, I don't know - but it sounds strange to me that your are not using the same WCF refence.
There are many solutions.
The team uses the same configuration (e.g. everyone uses localhost references)
You separate user from application settings (do not apply to all kind of settings nor projects)
Use transforms and solution configuration to map have per-environment setting
Use configSource to move config section in separate files that are not under version control
I do not think there is a perfect solution, but maybe you apply a mix of these. I strongly suggest to apply them in the stated order.

application config file clean up

a c# application which I worked on in the past went through a couple of namespace changes and assembly name changes.
As a result of this my application's config file that is generated when I build is full of older stuff that is of no use to me anymore.
I've tried deleting these sections. I tried deleting the whole config file and forcing VS to build me a new one but it keeps building me a copy from a LONG time back.
How can I force my application to give me a new config file whenever I want to?
edit: question was unclear. I'll try to add more.
Let's say for example that my application was called "mytools". I then changed the assembly and namespace settings for the program and now it is called "mytoolsPLUS". When I build my application and view the mytoolsPLUS.exe.config file I see in the <configsections> node I have two <sectiongroup> nodes, usersettings and applicationsettings. Within the usersettings <sectiongroup> node I have an entry for <section name=mytools.properties.settings type=sys.config.clientsettingssection....> but I also have an entry for <section name=mytoolsPLUS.properties.settings type=sys.config.clientsettingssection...>
This same sort of duplication occurs under my <connectionstrings> node and thus is the main reason I am posting this thread today. One of my end users got confused as to which connection string they needed to adjust to point to a backup test server. I looked into it more and found that I have lots of "old fragments" left over in my config file. I like using the settings class over a full xml file for small apps like this so I would like to figure out what I have done wrong here. I hope my explanation is clear enough for those who are reading.
Thanks for reading my post!
In your project, tree open the properties node directly under the project.
In there you will see a "Settings.settings" and "Settings.Designer.cs" file. Right click each of the files and choose "Open With.." and pick "Source code editor".
You should be able to clean up anything old from here.
You can also use a standard text editor to edit these.
In your project, there should be a file called App.config. You can delete the extra sectionGroups and other extraneous stuff there to clean-up your config file.

Settings.Default.<property> always returns default value instead of value in persistant storage (XML file)

I recently wrote a DLL in C# (.Net 2.0) which contains a class that requires an IP address. A co-worker of mine altered the class to retrieve the IP from a ".dll.config" (XML) file -- This apparently is automatically generated by the "Application Settings" file he created (Settings1.settings). The benefit of this was to allow the end-user to change the IP address in the XML/config file at will.
Unfortunately, when I check his code out of the tree and try to compile (or use) this new code, any application calling this DLL only gets the default value, rather than the value from the file.
The constructor that calls the config file looks like this:
public class form : System.Windows.Forms.Form
{
public form()
{
// This call is required by the Windows Form Designer.
InitializeComponent();
IP = IPAddress.Parse(Settings1.Default.IPAddress);
}
}
I found a reference to this problem on the MSDN forums where a user said:
the 'old' values (the ones you define at development time) are hard coded. If the franework isn't able to access or open the config file it will use the defaults instead. This will always happen if you use settings in a dll.
Does this mean that I cannot store an external value for a DLL in a config file? (My co-worker has somehow made this work...)
Since my framework appears to be unable to access or open the config file, how do I figure out why it's failing? Or even detect when this happens?
Decker: That helps a bit. Unfortunately, I am writing this DLL to a specification, so I don't actually have access to the Application's config file. As you'll note above, my co-worker created a "Settings1.settings" file. I didn't understand this at the time, but it seems now that adding the "1" keeps it out of the settings space of any application that calls it.
I guess what I'm trying to figure out is why the DLL doesn't seem to find the config file sitting next to it in the same directory. Tracing thru the code step-by-step reveals nothing.
As an aside, I can change the "Output Type" of my assembly from "Class Library" to "Windows Application" and add the following lines at the beginning of my DLL code:
[STAThread]
public static void Main(string[] args)
{
System.Windows.Forms.Application.Run(new form());
}
When I run this, it generates a different config file (a ".exe.config") and that one I can alter and have it pull the new data from the file. So I'm a bit confused. Any ideas?
I use this technique all time time. Often I have a library assembly that requires certain settings, and I need them set both by testing projects as well as the primary "executable" assemblies -- be they web projects or Windows service projects.
You're correct in that when you create a settings file for any project, it adds an application config file. The value you enter for any setting is stored in two places -- the config file AND in attributes on the classes created by the settings infrastructure. When a config file is not found, the values embedded in the attributes are used.
Here is a snippet that shows such an attribute:
Here is a snippet that shows the default value of the ConcordanceServicesEndpointName in the generated class:
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("InternalTCP")]
public string ConcordanceServicesEndpointName {
get {
return ((string)(this["ConcordanceServicesEndpointName"]));
}
}
What you want to do is copy the configuration section out of the app.config file from the library assembly project and merge it (carefully) into the applicable web.config or app.config for the main assembly. At runtime, that's the only config file that is used.
Here is an example:
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="LitigationPortal.Documents.BLL.DocumentsBLLSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<LitigationPortal.Documents.BLL.DocumentsBLLSettings>
<setting name="ConcordanceServicesEndpointName" serializeAs="String">
<value>InternalTCP</value>
</setting>
</KayeScholer.LitigationPortal.Documents.BLL.DocumentsBLLSettings>
</applicationSettings>
You should copy these sections into the "true" config file.
I'm addressing this exact issue in an application I'm in the midst of prototyping. Although Decker's suggestion of hacking the config files together should work I think this is a pretty inconvenient manual hack to perform as part of a build cycle. Instead of that I've decided that the cleanest solution is to just have each library parse its own library.dll.config file. Its still not perfect and it requires some extra boiler-plate code, but it seems to be the only way to get around the byzantine way that .Net handles these app.config files.
I have had this same problem for a long time - it's annoying.
I like the idea of making your own config file and having each DLL parse it, though it still might be easy to miss having to change the config.
One thing I have done in the past to at least make this a little easier is to make sure that any config values that the Setting1.Settings file are invalid.
For instance, I have a class that uses LINQ-To-SQL to talk to the DB. So it has a Setting1.settings file that it stores the connection string to database in. The default value that is entered (upon dragging and dropping the database tables into the designer) is the connection string of the dev database.
Once I have the DBML file created based off of the test database, I can go in and edit the Settings file and type in a database name like "FAKE_DATABASE".
That way, if you use the DLL in another project, and then forget to merge the config files to add in the proper config value for the DLL, at least you'll get an error saying something like "Cannot connect to FAKE_DATABASE".
Of course, if you have to work with the designer again, you'll have to change the value back to the value of your dev database.
Huge pain. They've gotta change this somehow.
Apparently your application is trying to read from the default config file (which is probably the application's config file). To make sure, add the key-value pair in the dll's config file to the application's config file, run the application and see if it is read this time.
I think I just found an explanation of why this isn't working for my DLL and my test application. Here is the concluding exception from some guy's blog:
The fix for this is to either make sure your application and the support assemblies have the same namespace or to make sure you merge the contents of AppName.exe.config and DllName.dll.config (yes when you compile a .dll now it generates this file, however it is ignored if you copy it to the application directory and is not automatically merged)
So either I have to keep the DLL and Application in the same namespace -or- I have to merge the contents of the DLL config file with the Application's config file.
(Doesn't this sort of defeat the purpose of the DLL? I thought a DLL was supposed to be an independent library.)
Perhaps this is why it works for my co-worker. The production application shares the same namespace as the DLL. (My test app clearly does not...)
UPDATE: I just sat down with my co-worker recently and talked about this problem again and it seems that it was never working for him either, but he hadn't realized it because he had set the initial value to be the same as the device we were trying to use. So of course it appeared to work at first, but as soon as we deployed it elsewhere with slightly different settings it was broken again.
I've seen a similar problem when using app.config. Try running your application from the .exe instead of from Visual Studio & see if it then behaves as expected.
It is possible that in your DLL you have the access modifier (for the Settings1.Settings) set to Internal (Friend for VB). Try changing the Access MOdifier to Public and see if that lets your application read/write values from dll's config.
The answer from Howard covers the theory.
One quick and dirty way of solving this is to parse the xml config file manually.
string configFile = Assembly.GetExecutingAssembly().Location + ".config";
XDocument.Load(configFile).Root.Element("appSettings")....
This code project article gives you some code which allows you to use a Class Library app.config file, and read it properly. And still use the Visual Studio GUI to manage the settings.
https://www.codeproject.com/Articles/246201/Settings-in-an-assembly-configuration-file
The mistake I think you all make is that you apparently make referece to the DLL Settings via Settings1.Default.IPAddress while you are simply suppossed to do this Settings1.IPAddress.
The difference is that when you use Settings1.Default.IPAddress the values are gotten from the hardcoded values imbeded in the assembly file (.dll or .exe) as Attribute [global::System.Configuration.DefaultSettingValueAttribute(...)].
While Settings1.IPAddress is the value that is editable in the file .dll.config (XML file)**. so any changes you make to the XML file, it is not reflected in hardcoded default value in the assembly.
Not this:
IP = IPAddress.Parse(Settings1.Default.IPAddress);
But try this:
*IP = IPAddress.Parse(Settings1.IPAddress);

Categories

Resources