App.config for dll - c#

We have an "engine" that loads dlls dynamically (whatever is located in a certain directory) and calls Workflow classes from them by way of reflection.
We now have some new Workflows that require access to a database, so I figured that I would put a config file in the dll directory.
But for some reason my Workflows just don't see the config file.
<configuration>
<appSettings>
<add key="ConnectString" value="Data Source=officeserver;Database=mydatabase;User ID=officeuser;Password=officeuser;" />
</appSettings>
</configuration>
Given the above config file, the following code prints an empty string:
Console.WriteLine(ConfigurationManager.AppSettings["ConnectString"]);
I think what I want is to just specify a config filename, but I'm having problems here. I'm just not getting results.
Anyone have any pointers?

If your code sample for reading the AppSettings is in your DLL, then it will attempt to read the config file for the application and not the config file for the DLL. This is because you're using Reflection to execute the code.

Funny, where I'm at we're doing something very similar and the config file loads just fine. In our case I think each new config file's name matches that of it's associated assembly. So MyLibrary.dll would have a file named MyLibrary.dll.config with information for that file assembly. Also, the example I have handy is using VB.Net rather than C# (we have some of each) and all the settings in there are for the VB-specific My.Settings namespace, so we don't use the ConfigurationManager class directly to read them.
The settings themselves look like this:
<applicationSettings>
<MyLibrary.My.MySettings>
<setting name="SomeSetting" serializeAs="String">
<value>12345</value>
</setting>
</MyLibrary.My.MySettings>
</applicationSettings>

I wrote this for a similar system. My recollection is that I used Assembly.GetExecutingAssembly to get the file path to the DLL, appended .config to that name, loaded it as an XmlDocument, navigated to the <appSettings> node and passed that to a NameValueSectionHandler's Create method.

Here is one way -
AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file");
Call in constructor.

If I recall correctly, the app.config will be loaded from your application directory, so if you are loading dlls from some other directory, you'll want the keys they need in your application's config file.

I'm not totally sure but I think that class only works with the path of the entry method of the AppDomain (the path of the exe most of the time) by default.
You need to call OpenExeConfiguration(string exePath) (Framework 2.0 and later) first to point to a different config file.

Related

Object reference not set to an instance of an object in windows service

Read a app.config value:
string configFile =
System.Configuration.ConfigurationManager.AppSettings["connStr"].ToString();
Config file:
<appSettings>
<add key="connStr" value="Data Source=Dolphin-PC;
Initial Catalog=jsptpd_SYS;
Persist Security Info=True;User ID=sa;
Password=ccir"/>
</appSettings>
Get an error:
Object reference not set to an instance of an object
the \program and debug\ folder contains app.config file.
Why woud this happen
Because, System.Configuration.ConfigurationManager.AppSettings["connStr"] is null
How could i deal it?
A more valid question. There isn't anything wrong with your code here. the main reason that you are finding it null is probably because your app.config is not present in the directory you are running the application from. It could be because app.config is part of some library and it is not copied to the output directory. You need to make sure that either app.config is in your main project or you copy it to the directory (you are running your applicatior from) explicitly.
To fixed the problem,you need to know the princeple of ConfigurationManager how to read the config file:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx
To solve this problem,you could make sure your bin/ directory generate yourprogram.exe.config file,so the ConfigurationManager could read.
If this file missing,you coud make sure your app.config attribute generate operation is not Embeded resource.If it is true,the app.config will embeded to the exe file and configurationmanager could not read.

Configuration from App.config isn't being pulled correctly

I'm trying to extract a URL I saved to the app.config file, but it's returning a blank string. Any ideas why?
string asdf = String.Format("{0}", ConfigurationManager.AppSettings["MemberUrl"]);
And the configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ForumUrl" value="http://www.dreamincode.net/forums/xml.php?showforum=" />
<add key="MemberUrl" value="http://www.dreamincode.net/forums/xml.php?showuser=" />
</appSettings>
</configuration>
If the app.config is part of a class library it probably isn't being copied to the bin folder properly (if at all).
The config file must be named <exefilename>.config for it to be picked up by the running application.
The App.config file in the application project (the one that produces an exe file, Console, WinForms, etc.) will copy and rename on deployment. Or if this is being executed from a web project it needs to go in the web.config.
Does this help?
All config information that your class library needs must be in the main projects App.config or web.config. In other words, if your app.config file is attached to the library it will NOT be read.
Go to the main application and add the appropriate keys/values to it's config file.
Sergio I just tried this is a console application and it works perfectly.
I would suggest that it's a class library; and not a main assembly that you have added your app.config file to.
When you do a build; look in the binary output folder Debug or Release and in there you should see a file named yourEXEfilename.config; if that file is not there then you will not get any output from the line of code you have above.
AppSettings will return a NULL string.
Hope this is of use
Kind Regards
Noel
there's no reason why that wouldn't work - do you have any other pertinent info ?
FYI, you dont need String.Format for what you're doing, the following is fine
string asdf = ConfigurationManager.AppSettings["MemberUrl"];

Where are config files for class libraries physically located?

My guess is that this question will fall under the category of "duh", but, nevertheless, I'm confused.
When using config files in, for example, a Windows Forms Application, the config file can be found in C:\Program files\CompanyName\ProductName\Application.exe.config. However, with the class library I'm developing I do not see a "ClassLibrary.dll.config" file in the install folder after installing it (in tandem with another project) from Visual Studio. Even though I do not see the file anywhere, retrieving data from it works correctly. Plus, running the following code from a method within the class library returns the path you would expect: C:\Program files\CompanyName\ProductName\ClassLibrary.dll.config.
If someone could shed some light on what I'm missing here, that would be really awesome.
public static string MyMethod()
{
Assembly assem = Assembly.GetExecutingAssembly();
Configuration config = ConfigurationManager.OpenExeConfiguration(assem.Location);
return "The assembly location was: " + assem.Location + Environment.NewLine +
"The config file path was: " + config.FilePath;
// Gives me "C:\Program files\CompanyName\ProductName\ClassLibrary.dll.config"
}
In a class library, the app.config file is pretty useless. Application setting values get stored in the Settings.settings file and are compiled into the Settings.designer.cs file.
If you modify the value of one of your application settings in app.config directly, that won't have an effect on the setting value seen while running the application. You have to actually open the Settings editor, at which point it will notice the difference between the app.config file and the Settings.settings file and inquire as to whether you'd like it to update your Settings.settings file using values from app.config.
Depends on the version of .NET. Prior to .NET 4.0, class libraries cannot use their own app.config files unless you do custom stuff to read the data in. In these scenarios, you should have the initialization of your class libraries require all of the appropriate data and pass that in from your consuming class's configuration (i.e. ultimately your winform's app.config file).
Your class library will use the config file of the executable that called it.
Your default value is stored in the dll.
But let's say you change the setting in code and save it. Where does it get stored for next time?
In WinXP look in:
C:\Documents and Settings\username\Local Settings\Application Data\
or in Windows Vista/7 look in:
C:\Users\username\AppData\Local\
You will find a folder named after your application and drilling down in to that folder, you will find a file named user.config.
For example:
C:\Documents and Settings\username\Local Settings\Application Data\MyApp\myapp.exe_urlla1ii3sytrhx0adqtjnjuc24oacqpgu4\1.0.0.0\user.config
Just to expand on #TLiebe's answer here, it is stored in the main assembly's settings file under a separate domain. For example:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<TestLib.Properties.Settings>
<setting name="TestSetting" serializeAs="String">
<value>2.8.0.0</value>
</setting>
</TestLib.Properties.Settings>
<UpdateTest.Properties.Settings>
<setting name="Token" serializeAs="String">
<value>{fV234hwolihj453lvB}</value>
</setting>
</UpdateTest.Properties.Settings>
</userSettings>
</configuration>

Relocating app.config file to a custom path

Is it possible to relocate the whole App.Config file to a custom path?
It seems a bit odd that the config file resides in the same folder as the exe, with Windows' new approcah of saving all program settings in c:\ProgramData and all.
An additional requirement we have is to programatically specify where to find the app.config file. The reason for this being that we spawn different service instances from the same exes, and would like to store each service's app.config in that service's settings folder under c:\ProgramData\\.
If still relevant, we have used the following I found on another suggested answer to another question here on Stack Overflow...
AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", "path to config file")
Worked great for us when we had issues loading app.config from DLL only...
Each AppDomain has/can have its own configuration file. The default AppDomain created by CLR host uses programname.exe.config; if you want to provide your own configuration file, create separate AppDomain. Example:
// get the name of the assembly
string exeAssembly = Assembly.GetEntryAssembly().FullName;
// setup - there you put the path to the config file
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = System.Environment.CurrentDirectory;
setup.ConfigurationFile = "<path to your config file>";
// create the app domain
AppDomain appDomain = AppDomain.CreateDomain("My AppDomain", null, setup);
// create proxy used to call the startup method
YourStartupClass proxy = (YourStartupClass)appDomain.CreateInstanceAndUnwrap(
exeAssembly, typeof(YourStartupClass).FullName);
// call the startup method - something like alternative main()
proxy.StartupMethod();
// in the end, unload the domain
AppDomain.Unload(appDomain);
Hope that helps.
I know this is an old question, but for those who just want to have their app.config in a different location then their binary output build location, the following works as microsoft intended it (and thus no need re-read and re-write the file to disk)
Define an app.config as you always do.
Define another config file where you want to have the actual configuration file
Change the app.config so that it refers to the configuration file
At runtime the settings from the configuration file will override the settings in the app.config (if present). And you are done.
Example app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<appSettings file="..\Config\settings.config">
<add key="port" value="1001"/>
</appSettings>
</configuration>
Note the file="..\Config\settings.config". You are completely free to define the path to the location where you want your users to change settings.
Example of the actual configuration file
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="port" value="1234"/>
</appSettings>
At runtime the setting port will have the value 1234.
More info see msdn
This worked for me.. (taken from http://msdn.microsoft.com/en-us/library/system.configuration.appsettingssection.aspx)
// open config
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// update appconfig file path
config.AppSettings.File = "C:\\dev\\App.config";
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
// Force a reload in memory of the changed section.
ConfigurationManager.RefreshSection("appSettings");
Then when you call
NameValueCollection settings = System.Configuration.ConfigurationManager.AppSettings;
or any operation to fetch the app config, the new path is used.
Hope this might help someone else who has same problem!
I am sorry if I misunderstand your request but can you not use
ConfigurationManager.OpenExeConfiguration Method (String)
Based on the change, is it possible that you can use
AppDomainSetup.ConfigurationFile Property
This is an ancient question, but I ran into this same problem and came up with a hacky workaround from a few minutes in reflector:
static public class ConfigHack {
static public void OverrideAppConfig(string path) {
((AppDomainSetup)
typeof(AppDomain)
.GetField("_FusionStore", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(AppDomain.CurrentDomain))
.ConfigurationFile = path;
}
static public void ResetConfigManager() {
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.Static | BindingFlags.NonPublic)
.SetValue(null, 0);
}
}
I've only used it on .NET2, but it looks the same in 4 in reflector. Of course I wouldn't recommend shipping this :P I only use it for quick internal things.
You could use astander's approach of calling OpenExeConfiguration. If you literally want to relocate your config file, you'll have to create your own app domain. In the process of setting up your app domain you get the chance to specify where the config file is located.
BTW, .NET config files aren't great for configuration, at least not the sort that users can modify: they're not like INI files or the registry. If you want flexibility over where your configuration comes from you're better off storing it separately.
If u use the registry, your problem can be resolved.
MSDN probably would help...
The element
simplifies servicing for component
assemblies. If one or more
applications use an assembly that has
a configuration file residing in a
well-known location, the configuration
files of the applications that use the
assembly can use the
element to
include the assembly configuration
file, rather than including
configuration information directly.
When the component assembly is
serviced, updating the common
configuration file provides updated
configuration information to all
applications that use the assembly

Windows Service Config File C#

I've developed a windows service application using Visual Studio 2008 / C#.
I have an app.config file in the project. When installed, the app.exe.config file appears beside the executable but it appears not to be reading the values from it when I try to access them through ConfigurationManager.AppSettings.
Has it copied the config file elsewhere or is there some other problem I don't know about?
Thanks in advance,
Martin.
Edit:
The config file name is infact my_exe_file_name.exe.config, it looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="RuntimeFrequency" value="3" />
</appSettings>
</configuration>
and I am trying to read via:
ConfigurationManager.AppSettings["RuntimeFrequency"]
The debug value I continually see is '1' and not '3'. Am I doing something wrong here?
I located the error and it was related to file permissions. After installing the service, my local user account didn't have access to modify the app.exe.config file.
The tool I was using to edit was not informing me it was being denied access to save the file - that's notepad++ if anyone is interested - so I couldn't see that it wasn't saving over the old config file.
Solved now, thanks everyone.
Martin.
When you are in debug mode check and see what settings are in the my_exe_file_name.vshost.exe.config Also make sure you adjust this in the app.config file. Visual studio should update the final config file in your bin/debug folders.
Maybe you are updating the wrong config file. You should double check that using
System.Configuration.ConfigurationManager.OpenExeConfiguration(PATH_TO_CONFIG);
Generally for the Windows Services that I write, i drop the appName.exe.config file into C:\WINDOWS\system32\
Perhaps you have an older version in that directory, which is where your service is getting the value, even though you've updated the config file in your project.
App.config file should be renamed to your_exe_file_name.exe.config and placed near the exe file.
Is it possible that you have more than one instance of the RuntimeFrequency entry defined? The ConfigurationManager reads the file from top to bottom and processes each setting individually. Therefore, the last value of RuntimeFrequency that is defined in the file is the one it will use.
If you want to know for sure if your file is being used, I would simply remove or comment out any definition for RuntimeFrequency (copy/paste errors do happen) and wait to see an application error when ConfigurationManager attempts to reference an entry in AppSettings that does not exist.

Categories

Resources