I cannot see a app.config file generated for a class library by the VS2008 wizard. In my research I found that in an application only one app.config exists.
Is it a bad thing to add an app.config manually to a class library or are there any other methods which will serve the purpose of an app.config in class library?
I need to store log4net config information inside the app.config file.
You generally should not add an app.config file to a class library project; it won't be used without some painful bending and twisting on your part. It doesn't hurt the library project at all - it just won't do anything at all.
Instead, you configure the application which is using your library; so the configuration information required would go there. Each application that might use your library likely will have different requirements, so this actually makes logical sense, too.
I don't know why this answer hasn't already been given:
Different callers of the same library will, in general, use different configurations. This implies that the configuration must reside in the executable application, and not in the class library.
You may create an app.config within the class library project. It will contain default configurations for items you create within the library. For instance, it will contain connection strings if you create an Entity Framework model within the class library.
However, these settings will not be used by the executable application calling the library. Instead, these settings may be copied from the library.dll.config file into the app.config or web.config of the caller, so that they may be changed to be specific to the caller, and to the environment into which the caller is deployed.
This is how it has been with .NET since Day 1.
Jon, a lot of opinion has been given that didn't correctly answer your question.
I will give MY OPINION and then tell you how to do exactly what you asked for.
I see no reason why an assembly couldn't have its own config file. Why is the first level of atomicy (is that a real word?) be at the application level? Why not at the solution level? It's an arbitrary, best-guess decision and as such, an OPINION. If you were to write a logging library and wanted to include a configuration file for it, that would be used globally, why couldn't you hook into the built-in settings functionality? We've all done it ... tried to provide "powerful" functionality to other developers. How? By making assumptions that inherently translated to restrictions. That's exactly what MS did with the settings framework, so you do have to "fool it" a little.
To directly answer your question, simply add the configuration file manually (xml) and name it to match your library and to include the "config" extension. Example:
MyDomain.Mylibrary.dll.Config
Next, use the ConfigurationManager to load the file and access settings:
string assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath;
Configuration cfg = ConfigurationManager.OpenExeConfiguration(assemblyPath);
string result = cfg.AppSettings.Settings["TEST_SETTING"].Value;
Note that this fully supports the machine.config heierarchy, even though you've explicitly chosen the app config file. In other words, if the setting isn't there, it will resolve higher. Settings will also override machine.config entries.
In fact, the class library you are implementing, is retrieving information from app.config inside the application that is consuming it, so, the most correct way to implement configuration for class libraries at .net in VS is to prepare app.config in the application to configure everything it consumes, like libraries configuration.
I have worked a little with log4net, and I found that the one who prepared the application always had a section for log4net configuration inside main app.config.
This configuration for example has a log4net section.
If you want to configure your project logging using log4Net, while using a class library, There is no actual need of any config file. You can configure your log4net logger in a class and can use that class as library.
As log4net provides all the options to configure it.
Please find the code below.
public static void SetLogger(string pathName, string pattern)
{
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = pattern;
patternLayout.ActivateOptions();
RollingFileAppender roller = new RollingFileAppender();
roller.AppendToFile = false;
roller.File = pathName;
roller.Layout = patternLayout;
roller.MaxSizeRollBackups = 5;
roller.MaximumFileSize = "1GB";
roller.RollingStyle = RollingFileAppender.RollingMode.Size;
roller.StaticLogFileName = true;
roller.ActivateOptions();
hierarchy.Root.AddAppender(roller);
MemoryAppender memory = new MemoryAppender();
memory.ActivateOptions();
hierarchy.Root.AddAppender(memory);
hierarchy.Root.Level = log4net.Core.Level.Info;
hierarchy.Configured = true;
}
Now instead of calling XmlConfigurator.Configure(new FileInfo("app.config")) you can directly call SetLogger with desired path and pattern to set the logger in Global.asax application start function.
And use the below code to log the error.
public static void getLog(string className, string message)
{
log4net.ILog iLOG = LogManager.GetLogger(className);
iLOG.Error(message); // Info, Fatal, Warn, Debug
}
By using following code you need not to write a single line neither in application web.config nor inside the app.config of library.
Actually, for some rare case you could store app.config in class libraries (by adding manually) and parse it by OpenExeConfiguration.
var fileMap =
new ExeConfigurationFileMap {ExeConfigFilename =
#"C:\..somePath..\someName.config"};
System.Configuration.Configuration config =
ConfigurationManager.OpenMappedExeConfiguration(fileMap,
ConfigurationUserLevel.None);
You should really estimate the real need of this. For abstract data its not the best solution, but "Config Sections" could be very usefull!!
For example, we organised our N-Tier WCF architecture decoupled, without any metadata, simply by using Unity Container and Injection Factory based on Channel Factory T. We added externall ClassLibrary dll with just [Service Contract] Interfaces and common app.config in order to read endpoints from clientsection, and easily add/change them at one place.
You do want to add App.config to your tests class library, if you're using a tracer/logger. Otherwise nothing gets logged when you run the test through a test runner such as TestDriven.Net.
For example, I use TraceSource in my programs, but running tests doesn't log anything unless I add an App.config file with the trace/log configuration to the test class library too.
Otherwise, adding App.config to a class library doesn't do anything.
Your answer for a non manual creation of an app.config is Visual Studio Project Properties/Settings tab.
When you add a setting and save, your app.config will be created automatically.
At this point a bunch of code is generated in a {yourclasslibrary.Properties} namespace containing properties corresponding to your settings. The settings themselves will be placed in the app.config's applicationSettings settings.
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ClassLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<ClassLibrary.Properties.Settings>
<setting name="Setting1" serializeAs="String">
<value>3</value>
</setting>
</BookOneGenerator.Properties.Settings>
</applicationSettings>
If you added an Application scoped setting called Setting1 = 3 then a property called Setting1 will be created.
These properties are becoming at compilation part of the binary and they are decorated with a DefaultSettingValueAttribute which is set to the value you specified at development time.
[ApplicationScopedSetting]
[DebuggerNonUserCode]
[DefaultSettingValue("3")]
public string Setting1
{
get
{
return (string)this["Setting1"];
}
}
Thus as in your class library code you make use of these properties if a corresponding setting doesn't exist in the runtime config file, it will fallback to use the default value. That way the application won't crash for lacking a setting entry, which is very confusing first time when you don't know how these things work.
Now, you're asking yourself how can specify our own new value in a deployed library and avoid the default setting value be used?
That will happen when we properly configure the executable's app.config. Two steps. 1. we make it aware that we will have a settings section for that class library and 2. with small modifications we paste the class library's config file in the executable config. (there's a method where you can keep the class library config file external and you just reference it from the executable's config.
So, you can have an app.config for a class library but it's useless if you don't integrate it properly with the parent application.
See here what I wrote sometime ago: link
There is no automatic addition of app.config file when you add a class library project to your solution.
To my knowledge, there is no counter indication about doing so manualy. I think this is a common usage.
About log4Net config, you don't have to put the config into app.config, you can have a dedicated conf file in your project as well as an app.config file at the same time.
this link http://logging.apache.org/log4net/release/manual/configuration.html will give you examples about both ways (section in app.config and standalone log4net conf file)
I would recommend using Properties.Settings to store values like ConnectionStrings and so on inside of the class library. This is where all the connection strings are stores in by suggestion from visual studio when you try to add a table adapter for example.
enter image description here
And then they will be accessible by using this code every where in the clas library
var cs= Properties.Settings.Default.[<name of defined setting>];
Related
.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()
This may be the simple question to answer, but I am struggling to resolve.
I have Web.config with the following values in my Web Application.
<appSettings>
<add key ="FirstName" value ="Prasad"/>
<add key ="LastName" value ="Kanaparthi"/>
</appSettings>
I have App.config with following value in my Class Library (Say Lib).
<appSettings>
<add key ="FullName" value ="Prasad Kanaparthi"/>
</appSettings>
The class library(Lib) is pluggable component, I have added the Class Library(Lib) reference in my Web Application.
I have the below code in my Class Library(Lib). When i create instance for GetAppSettings in my web application i can see below responses.
namespace Lib
{
public class GetAppSettings
{
public GetAppSettings()
{
var FirstName = ConfigurationManager.AppSettings["FirstName"]; // O/P : Prasad
var MiddleName = ConfigurationManager.AppSettings["LastName"]; // O/P : Kanaparthi
var FullName = ConfigurationManager.AppSettings["FullName"]; // O/P : null
}
}
}
The Question is how can i read FullName from App.config which is Class Library (Lib).
Note: Since my Lib is pluggable component, So the consumers can change the FullName of their own. I cannot merge values to Web.confing from App.config.
You have to merge both configuration sections and place all settings in the main configuration file of your application. In case of the web applciation it would be the web.config.
The short answer is: you can't. The application using your library won't pay any attention to your app.config. You could use a settings file instead or perhaps go a longer way around, abstract out the configuration manager and have it programmatically read your app.config as an XML file in the application's output directory in order to include its settings. Understandably, neither option is ideal.
While I don't work often with web applications, in my desktop application I often face a similar issue. I've been using the code provided by Daniel Hilgarth https://stackoverflow.com/a/6151688/2212458 to temporarily switch configuration files. The plugin loader can pull in the plugin configuration file and then restore its own.
I want to use a single app.config by 3 different projects.
How to access the configurations?
ConfigurationManager.AppSettings["config1"]
Let's say you have this folder structure:
Solution
Project1
Project2
Project3
Do this:
Create the App.config file in the Solution level folder. You won't find an option to add an App.config file from the templates, so just create a new empty text file with the name App.config, and paste in the contents of a regular App.config file.
For each project in Solution Explorer:
Right click and select Add > Existing Item
Locate the file
Select Add as link from the drop down box next to the Add button.
Edited to add:
You correctly state that the above method only shared the file up to build-time. To use a shared file at run-time, see the answers to this question.
The common config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="appSettings"
type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
/>
</configSections>
<appSettings>
<add key="key1" value="value1"/>
</appSettings>
</configuration>
To access mapped config file
ConfigurationFileMap fileMap = new ConfigurationFileMap(file); //Path to your config file
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
string value = configuration.AppSettings.Settings["key1"].Value;
I have found the button, and opened
the app.config as link, however that
caused when build to again create
separate config file for each project,
and therefore, when deploying the 3
project, i will have 3 config files.
What I wanted to do, is keeping a
single file for all projects in a
certain solution. Can I do that?
Yes - you can do it, but should you do it?
The basic assumption in a .NET app is that one app = one config file. Out of the box, and with an easy method, you cannot share config files between applications.
If you create your own custom config sections, you could "outsource" those to external files, which could be shared. Imagine you create your own custom config section called "MyConfiguration", then your app.config would look something like that:
<configuration>
<configSections>
<section name="MyConfiguration"
type="MyConfigurationSection, MyConfigurationAssembly" />
</configSections>
<MyConfiguration>
<nestedElement>
<dateTimeValue>10/16/2006</dateTimeValue>
<integerValue>1</integerValue>
</nestedElement>
</MyConfiguration>
</configuration>
You could have your "MyConfiguration" section in its own file, and reference it from your app's config:
<configuration>
<configSections>
<section name="MyConfiguration"
type="MyConfigurationSection, MyConfigurationAssembly" />
</configSections>
<MyConfiguration configSource="MyConfiguration.config" />
</configuration>
and your "MyConfiguration.config" would then contain:
<MyConfiguration>
<nestedElement>
<dateTimeValue>10/16/2006</dateTimeValue>
<integerValue>1</integerValue>
</nestedElement>
</MyConfiguration>
By doing this, you could "externalize" and thus share at least the bulk of your config settings - provided they're in your own custom config sections.
For more info and an excellent intro to .NET 2.0 and up configuration mysteries, see Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.
Unraveling the mysteries of .NET 2.0 configuration
Decoding the mysteries of .NET 2.0 configuration
Cracking the mysteries of .NET 2.0 configuration
Highly recommended, well written and extremely helpful!
Marc
Here's the "Add existing item" dialog in VS 2008:
Click on the little dropdown indicator on the "Add" button and pick "Add as Link" from the context menu.
Marc
One design option is to avoid accessing the app.config directly from your class library projects altogether, thus avoiding the extra external dependency.
Rather, only your executable project knows about the config file and it can explicitly pass the appropriate config information to the libraries when it creates objects from them or initializes them.
I understand this is a old question but there is a much easier way of achieving this. If you are using Visual Studio 2008 or higher there is a Project type called "Shared Project".
A Shared Project can have pretty much anything that another types of Projects can contain. This is not only for C# but for all languages that VS2015 supports. When something is included in the Shared Project it is available to other projects after you add a reference to it (see below).
The major difference with Classes in a Shared Project VS a Shared Library is when you compile the program everything that is in the Shared Project will be Compiled directly into your project not as a separate file (.dll, .exe). Think of it like everything that is in the Shared Project is inserted into the other projects. Here is a small tutorial on setting this up and using it:
Visual Studio 2015 - Shared Project Tutorial:
Create the New Shared Project by selecting File->New->Project or Right Click on the Solution in the Solution Explorer and select Add->New Project. When the Dialog shows up select "Shared Project", give the Project a name TestShared in this example.
After the New Project is added you can add anything you need to be available to other projects. In this case we will add the app.config. Right Click on the Shared Project and select Add->New Item. Select Visual C#->Data->XML File naming it obviously to app.config.
Finally add a reference to the Shared Project by Right Clicking the Project that you need to share the project with and select Add->Reference. In the Reference Manager Dialog select your Shared Project, it will be listed under the "Shared Projects" item on the Left.
Now everything that is in the Shared Project is available in the other project, there is no need to do any using imports or anything like that. It simply works. This pattern is quite handy when you are developing a program and need to have several different GUI's (Windows, iOS, Android etc). For example you could have one shared project for the "Core" functionality and then have a separate GUI Project for each of the different Operating Systems you want to support in your program.
I realize that this is a older question but since this showed up in Google I thought I would answer this so when others are looking for the same thing they know about this very powerful VS feature.
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config = ConfigurationManager.OpenExeConfiguration(Path.Combine(#"D:\", "config.exe"));
foreach (string key in config.AppSettings.Settings.AllKeys)
{
string value = config.AppSettings.Settings[key].Value;
ConfigurationManager.AppSettings.Set(key, value);
}
I have a .net solution having a reference hierarchy like this
MyWinApp->ServerCore->DataAccess
where the last two are class libraries and myWinApp is a windows app.
Now, each time I want to run this project on different servers I need to rebuild the project since I couldn't manage to separate the configuration file(app.config) of DataAccess project that has connection string related configurations.
How can I separate database configurations from the application code? I tried to build action options but it doesn't work :S What might be the most feasible solution?
Thanks in advance
The configuration should most likely go with the MyWinApp project. The configuration file goes with what is executing. So if you make an installer for your application, it'll have a configuration file called MyWinApp.exe.config that was created from your App.Config.
Basically the app.config with your Datalayer.dll doesn't really do much.
What you might want to do is look at how the configSource property works for configuration files in .net here: http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx and see if this is what you're looking for. This lets you set a configSource for your connection strings that you can change per machine.
All I do is setup a simple xcopy before a deploy and I have the correct configuration settings before deploying an asp.net app. If you have to package an installer, copying the correct files before building the installer should do the trick as well.
For my DAL projects I typically have a DataLayer.dll.config file but I actually add the ConnectionString entries to my Program.exe.config file. I don't know that you need anything special for this. Possibly just reference a static readonly string or something from the DataLayer.dll in the Program.exe?
Or, do you really want to have separate configuration files? If so then you can use the ConfigurationManager class to open a loose configuration file with the OpenMappedMachineConfiguration method. See MSDN ref here: http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.openmappedmachineconfiguration.aspx
I think you can use applicationSettings to include configuration for specific referenced assemblies:
For example:
<configuration>
<applicationSettings>
<ProjectName.Properties.Settings>
<setting name="ConnectionString" serializeAs="String">
<value>YourConnectionStringHere</value>
</setting>
</ProjectName.Properties.Settings>
</applicationSettings>
</configuration>
Where "ProjectName" is the name of the reference you need to configure. Each project can have it's own app.config with the above applicationSettings entry and a value specific to the project itself.
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);