application config file clean up - c#

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.

Related

Documenting external dll's with sandcastle

I'm currently developing an application, which requires external dll's which I do not control. I'd like to add documentation for these classes, so that others can understand why I'm making certain calls I'm making to these external DLL files.
Adding the external DLL files to the documentation sources does indeed log the classes, but all the summaries and other information is unavailable. Is it possible to document these files (Preferably without having to decompile/recreate the assembly as a project), so I can generate the related HTML documentation with sandcastle?
I've tried to keep Sandcastles working directory enabled, to see if the .xml files (That I see were copied over from my other projects) were somehow generated and placed in this directory. This doesn't seem to be the case, no files were generated, and it goes straight to generating the html files.
As far as I understand your question about creating documentation for an external DLL use case I see two possible ways that you can go:
Add "missing" notes for all items of the external DLL that you might want to document or/and
add conceptual topics to your own program documentation.
My sample solution WindowsApplication2 project has a form to add two values using a simple PDUNZDLL. A Sandcastle help file builder project "Documentation1" was added and two Documentation Sources (at this stage without XML comment file, see first snapshot below). You know - a DLL without XML comments file is resulting in a red missing summary.
Proposed solution (1):
Create a blank XML comments file like the following and name it after the assembly with a .xml extension e.g. PDUNZDLL.xml
<?xml version="1.0"?>
<doc>
<assembly>
<name>PDUNZDLL</name>
</assembly>
<members>
</members>
</doc>
Save this file to the e.g Debug folder D:\Visual-Studio-2015\Projects\WindowsApplication2\WindowsApplication2\bin\Debug
Double-click the "Project Properties" (see second snapshot below)
In the Component Configurations dialog, add the "IntelliSense Component" to the project.
Select "Missing Tags" and set the project's Show Missing Tags properties to your liking. This will force the build to add "missing" notes for all items that you might want to document.
Build the project and you will find a new XML comments file named after the assembly in the project's output folder e.g. D:\Visual-Studio-2015\Projects\WindowsApplication2\Documentation1\Help
Edit the <member> elements in the XML comments file to add the comments that you want for each member as shown in the second snapshot.
When you are done, replace your original placeholder file e.g. D:\Visual-Studio-2015\Projects\WindowsApplication2\WindowsApplication2\bin\Debug\PDUNZDLL.xml with the one generated from the build with your edited comments. ReBuild your documentation project.
This is of course time consuming as any help authoring for applications. And it was actually the task of the DLL developer.
Proposed solution (2):
Reading between your lines "... so that others can understand why I'm making certain calls I'm making to these external DLL files." leads me to the suggestion to add a supplementary documentation to your own program.
So, what I mean is to add conceptual topics describing how you call the features of the external DLL files.
I removed the the DLL under "Documentation Sources",
added a new folder "ExternalDLL",
added a new item Conceptual and Walkthrough,
double-click ContentLayout.content in Solution explorer,
and did all the steps for content layout, ReBuild the documentation project resulting in a help file like shown in the third snapshot below (see background info too).
Happy help authoring!

How to preserve app settings from a referenced assembly?

I have an app MainApp that references another project MyDLL.dll. Inside the MyDLL project I have made some user settings in a Settings.settings file that may be changed at runtime. So it appears that these settings get saved in the app.config file of MyDLL. But the problem is, the main project is MainApp, and MyDLL.dll.config does not, so far as I can see, get copied to the MainApp output folder. This is reflected in the fact that even though I save the settings in the code of MyDLL, the next time I run MainApp the settings have gone back to the default.
I must be missing something really obvious here. There has to be a way for related assemblies to preserve their settings values. But how?
While you can add an app.config to a library project, it has no effect to do so. Configuration is linked to the application, not the library.
You need to create the settings and configuration in your application itself. You can do something like including the library's app.config if you really wanted to, but that would probably not do what you want, either. It's best to just handle your configuration in the application.
Why is this so? Because what's to say it's valid to have user settings for your library in the first place? A library should not be tied to any particular kind of application. What if you used it in a Windows Service or an ASP.NET application?

Howto work with Properties.CustomSettings

According to MSDN, one can add customized settings files to ones project for convenient management of groups of settings.
So I created a custom settings by visual designer, set all properties as a User Scoped to be able to save them.I bind some control properties to this customized settings. And change some values mannually through Properties.CustomSettings.MyValue = x;
But when I do Properties.CustomSettings.Default.Save() - nothing happens. The changes are not persisted between application run (I'm aware about Debug version change) .
I searched a file in the directorites that ConfigurationManager gives me (according to this post) but didn't find any track of this CustomSettings.
So, what is the trick with saving this Customized Settings Files and How to save Customized Settings Files?
Ok, now I've got a right answer. Everything is OK that this custom settings were created under the dll file.
The problem is with this question
Application.UserAppDataPath strange behaviour
If one have AssemblyVersion with automatic Build and Revision Numbers and have AssemblyFileVersion in AseemblyInfo.cs, say, of exe that uses this dll, then Application.UserAppDataPath will throw ArgumentException "Illegal characters in path." Application.UserAppDataPath is used to build path to this config file to save this CustomSettings.
But ApplicationSettingsBase just eats all exceptions that happens inside, so the file is just not saved and nobody could even think about AssemblyFileVersion in AseemblyInfo.cs of exe...
Ohhh my god... 8 hours of fighting with this ... feature...

Updating config file and updating the values in application

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.

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