I manage my application-settings using the setting-designer in VS2008.
"The exact path of the user.config files looks something like this:"
<Profile Directory>\<Company Name>\
<App Name>_<Evidence Type>_<Evidence Hash>\<Version>\user.config
Is there to a way to customize this path? I would prefer something like this:
<Profile Directory>\<Company Name>\
<App Name>\<Version>\user.config
I noticed that white-spaces were replaced by underscores in the "Company Name" in the new created folder ("Test Company" --> "Test_Company"). I really wish to turn off this behavior.
You know, I could write a new XML-based setting-handler, but I would like to use the setting-designer.
Building on Chucks excellent answer:
Implement a new partial class based on Settings.Designer.cs, so the Settings Designer does not wipe out the attribute when changes are made:
I created the following class that can be put in an external project. It allows the config to be project.dll.config. By Inheriting and Overriding ConfigPath allows any path you like. I also added support for reading System.Collections.Specialized.StringCollection. This version is for Application settings.
Make sure dependent projects include the project.dll.config file by add a post-build event:
You would have to implement your own SettingsProvider to customize the path.
See this Client Settings FAQ
It hasn't been easy to find good info on implementing a custom settings provider so I'm including a complete implementation below (bottom.) The format of the user.config file is retained, as well as the functionality within the .settings designer. I'm certain there are parts that can be cleaned up a bit, so don't hassle me :)
Like others, I wanted to change the location of the user.config file and still get the fun and fanciness of working with the .settings files in the designer, including creating default values for new installations. Importantly, our app also already has other saved settings objects at a path (appData\local\etc) in which we have already decided, and we didn't want artifacts in multiple locations.
The code is much longer than I'd like it to be, but there is no SHORT answer that I could find. Though it seems somewhat painful just to be able to control the path, creating a custom settings provider in itself is still pretty powerful. One could alter the follwing implementation to store the data just about anywhere including a custom encrypted file, database, or interact with a web serivice.
From what I've read, Microsoft does not intend on making the path to the config file configurable. I'll take their word for it when they say allowing that would be scary. See (this) post. Alas, if you want to do it yourself you must implement your own SettingsProvider.
Here goes..
Add a reference in your project to System.Configuration, you'll need it to implement the SettingsProvider.
Easy bit...Create a class which implements SettingsProvider, use ctrl+. to help you out.
Another easy bit...Go to the code behind of your .settings file (there is a button in the designer) and decorate the class to point it to your implementation. This must be done to override the built in functionality, but it does not change how the designer works.(sorry the formatting here is weird)
[System.Configuration.SettingsProvider(typeof(YourCompany.YourProduct.CustomSettingsProvider))]
Getting the path: There is a property called "SettingsKey" (e.g. Properties.Settings.Default.SettingsKey) I used this to store the path. I made the following property.
Storing the settings values. I chose to use a dictionary. This will get used extensively in a bit. I created a struct as a helper.
The magic. You must override 2 methods, GetPropertyValues and SetPropertyValues. GetPropertyValues recieves as a parameter what you see in the designer, you have to opportunity to update the values and return a new collection. SetPropertyValues is called when the user saves any changes to the values made at runtime, this is where I update the dictionary and write out the file.
Complete solution. So here's the entire class which includes the constructor, Initialize, and helper methods. Feel free to cut/paste slice and dice.
Here is an easier, briefer alternative to creating a custom settings class: change your app's evidence so that the "url" part is a constant rather than being based on the location of executable. To do this, you need to modify the default AppDomain when the program starts. There are two parts: setting app.config to use your AppDomainManager, and creating an AppDomainManager and HostSecurityManager to customize the Url evidence. Sounds complicated but it's much simpler than creating a custom settings class. This only applies to unsigned assemblies. If you have a signed assembly, it's going to use that evidence instead of the Url. But the good news there is your path will always be constant anyway (as long as the signing key doesn't change).
You can copy the code below and just replace the
YourAppName
bits.DefaultAppDomainManager.cs:
app.config excerpt: