How do I save custom configuration sections during runtime? - c#

My application allows the user to add additional items to a combobox that get saved in a custom configuration section. The issue is that the save() call fails because my app is installed to C:/Program Files... which do not have read-write permissions so the user must run my app as Administrator.
Is there a more skillful way of saving user-added UI elements that persist? I looked into user settings but it doesn't seem like there is a way to save collections.

.NET doesn't really support writing to the app.config at runtime. You can do it, but you run into situations with permission. Writing to the app.config at runtime is generally an indication of user-scoped configuration. This is generally done with user-scoped configuration items within Properties.Settings which stores defaults in app.config and writes new/changes to the user's AppData.
In terms of custom configuration, with user-scoped settings, it really doesn't apply. You can simply use your own types in the Settings designer.

User settings (http://msdn.microsoft.com/en-us/library/bb397750(v=vs.90).aspx) are the best match for what you want. You could serialize the collection to JSON and save that as a string-typed setting.

Related

How to get an Application Settings shared to all users that could be changed at run time

I need some setting of an application that will be shared among all users of the computer, but could also be changed at at run time. That seam simple, but according to the Application Settings MSDN article, it's either one or the other.
There are two types of application settings, based on scope:
Application-scoped settings can be used for information such as a URL for a Web service or a database connection string. These values are associated with the application. Therefore, users cannot change them at run time.
User-scoped settings can be used for information such as persisting the last position of a form or a font preference. Users can change these values at run time.
I could write code to edit the app.config XML file, but since it's located in the program directory, it's protected under windows 7. So this is not possible without elevating the program or playing with NTFS rights.
So I need the configuration file to be written in a common folder like System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData).
But this is a fairly common requirement!
So, I'm wondering if there a simple way of achieving this without reinventing the wheel, or if I have to write my own Setting Manager.
After reading the answers here and playing with the ConfigurationManager.Open methods I ended up with the following:
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "MyApp", "MyApp.config");
Configuration MyAppConfig = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = path }, ConfigurationUserLevel.None);
The nice part is the file doesn't have to exist, and if you call Save() on it, it will create the folder and the file for you. AppSettings["key"] didn't work though so I had to use
MyAppConfig.AppSettings.Settings["key"].Value
to read and write an existing value and
MyAppConfig.AppSettings.Settings.Add("key", value)
to add a new value.
I have had a similar problem and ended up writing my own settings class. It was very basic. I created a Settings class with the properties I needed, and a SettingsManager with Save() and Load() methods that simply serialized/deserialized the object via XmlSerializer into/from a file.
Yes, it is your own code, but it is very simple code, takes less time than trying to figure out whether there is a component providing what you need and how to customize it.
The Application Settings infrastructure does not support this - only non-editable application data and user-scoped data are supported. You can easily read and write your own XML into the CommonApplicationData folders, however, instead of using the application data.

Letting users edit config file after deployment

I have a program which I'm going to deploy using the package for deployment built into VS.
Now I have an app.config file which I want the user to be able to modify (even after running the program), but I have no idea where exactly the installer dumps the files, and I'm not expecting the users to root around their filesystem.
What I was thinking is - I ask the user to specify some directory (which needs to happen anyway since its a game) - I check for the config file there, and if its not there, I copy it from the root directory the program can see - then read the one in the 'save' folder.
That said, its sounding like a very ugly and hacky solution - is there a better one?
I wouldn't be encouraging users to modify the app.config. The app.config is copied into the same directory as your app exe and usually contains settings which your app depends on to run correctly e.g. DB connection strings, system defaults etc. Your playing a dangerous game by letting users change settings in there directly.
A safer approach would be to export another XML file into the users documents folder where they can override app settings. Have your app load in the app.config first then override those values with any settings found in the users own config file.
I would also recommend implementing some sort of UI for this, even if its really basic. Your average user isn't going to be comfortable editing XML directly, too much margin for error.
You could use the application (or user) settings to persist any changes that the user might want to make in the configuration. See the ApplicationSettingsBase class and this article.
Say your application contains a user setting called Score, managed internally by a class called MyUserSettings:
public class MyUserSettings : ApplicationSettingsBase
{
[UserScopedSetting()]
[DefaultSettingValue(0)]
public int Rank
{
get
{
return (int)this["Score"];
}
set
{
this["Score"] = value;
}
}
}
You can save the current values, usually when the main form is closing, using the Save method:
myUserSettings.Save();
If you want users to modify some settings directly, you can use a property grid or your own form that binds the instance of MyUserSettings class.
If the settings are marked as "User", then the values would be stored in the user.config file, in %InstallRoot%\Documents and Settings\username\Local Settings or %InstallRoot%\Documents and Settings\username\Application Data (for roaming profiles).

Writable .config file for all users in application directory?

I need to have a common application settings file and i need it to be editable by the application at runtime.
I don't want to use the build in settings operation by putting "User" in settings scope because it gets saved in users local directory.
On the other hand i cant use the .config with "Application" as i cannot save into this file from within the application.
One might say "Create your own save settings XML file its easy"..Yes probably it is but i wonder what is the solution for a common writable config file with MS build in classes?
To have data, whatever the format, updateable by all users then all users need to be able to save to whatever container holds that data.
This applies whatever the format, from text file to RDBMS.
The problem with a file that you manage (eg. .config (XML) file) is twofold:
Concurrency.
Access Control.
The ConfigurationManager and associated classes will write to a .exe.config file with applicable declaration of the configuration elements and properties, but the underlying file has to be writeable. You'll need to:
Set an ACL in an installer so all (applicable) users have write access. This means outside the application they can write as well, this is unavoidable as there is no ability to set access control based on application.
Install outside Program Files. UAC virtualises writes to Program Files (so applications assuming all users can write anywhere don't break), but this also means it cannot be used for shared modifiable data.
Concurrency is another problem. What is two users both modify the shared data together? One user will overwrite the others changes unless you implement some locking and reloading on changed.
Consider using a multi-user database for the data instead. They are designed for this kind of thing, Config files are not.
Update (based on comment):
To have a (non-admin) user update a .exe.config in Program Files will still hit UAC virtualisation (ie. any writes will be directed to a per-user location, and not-visible to anyone else).
Easier to use the ConfigurationManager.OpenExeConfiguration(string) method to load a .config from some shared location (eg. in C:\ProgramData1) which has an appropriate ACL. The returned Configuration object has all the capabilities of the implicit load from .exe.config for <appSettings> as well as custom sections, plus access to Save and SaveAs.
1 Of course using correct methods to get actual local path, not hardcoding.

How do I create editable configuration settings in a C# WinForms application?

I have configuration values saved in an app.config. I want to create a WinForms application which shows all the AppSettings values in a form. The user should be able to change the settings values and save them back to the app.config.
As long as your values are in the appConfig section of the app.config file, you can simply use System.Configuration.ConfigurationManager.
ConfigurationManager.AppSettings - MSDN
Here's an old blog post explaining EXACTLY how to do what you're looking for:
Read/Write App.config
If you store the settings using the Settings.settings file in the Properties folder you can just do:
Properties.Settings s = new Properties.Settings();
And then all the settings will be properties of s (you can define them as a specific type even) and if they're set as user settings you can change them.
Just call Reload or Save on the instance of Settings to read/store from/to disk.
I was successful with using the method Justin Niessner suggested. One caveat to watch out for: When you are testing this in visual studio, the app.config itself won't be edited if you are debugging the application. The config file that is modified is the ProjectName.vshost.exe.Config
Have a look at System.ConfigurationManager. There's a huge example on the MSDN page showing almost all the necessary functionality to configure, alter, save, etc, all in the language of your choice.
The ConfigurationManager class
includes members that enable you to
perform the following tasks:
Read a section from a configuration file.
Read and write configuration files as a whole
Support configuration tasks.

C# Application Configuration Data

Hey, I want to store application configuration data. Currently, I'm using INIs but they are too old and now I want to try something new. I'm on .NET platform using C#.
What solutions do I have? app.configs?
The scenario here is like that, I want to let other programs read the configuration data.
Yes, the various .config files (app.config, web.config, etc..) have replaced INI and, to a certain extent, the Registry as the preferred means of storing configuration data for your application.
Any program, .Net or otherwise, can read those files. .Net has the ConfigurationManager class and other languages can simply do XML parsing to get the values they need.
The standard approach with .NET is to use app.config files for application settings and user.config files for user specific settings (the location varies between XP and Vista though).
There's nothing to stop other programs reading the configuration data, you just need to have a configuration setting in the second (or third) application that tells it where to look.
The app.config would be the preferred way of doing things in .NET. Should work fine to read from other applications as well, as long as you give them the right path to the file. And it's just an XML file, so you can read it from non .NET apps as well.
If you're using Visual Studio, you can use Application Settings for this purpose. Just open the automatically added Settings.settings or create another one. They will be automatically available in Properties.Settings.Default and are stored as XML. You can also have multiple settings files for different purposes.
This is a Visual Studio concept rather than a .NET concept.
I often use an SQL table to hold my application settings. I create a singleton class, ususally called AppSettings, that I load with data from the table. The AppSettings class is then used to get the config values instead of directly accessing the config files. For ASP.Net apps, I instantiate the AppSettings class in the Application_Start event in Global.asax.cs.
Doing this gives me a way to allow the user to control some of the app settings, e.g. an email address for notifications. It also can simplify things when maintaining prod, QA, and dev versions of the app (assuming you have separate database instances for each)

Categories

Resources