Editing/Modifying C# Application Settings - c#

The .NET configuration settings feature is not as flexible as I would like.
If I understand Application Settings correctly, I am limited as to when I can change/edit settings. In C#, Application Settings are divided into two different types or scopes ("Application" and "User"), but both have limitations in regard to how they can be changed or modified. The following table demonstrates the differnce:
SCOPE: | EDIT AT DESIGN-TIME: | EDIT AT RUN-TIME: | EDIT BETWEEN SESSIONS:
---------------------------------------------------------------------------------------
User | Setings.settings | Settings.Default.Save() | *Not supported*
Application | Setings.settings | *Not supported* | edit app.exe.config
Is there any "built-in" settings functionality that will allow me to edit settings by all three mechanisms? One of the primary motivations for using a configuration file is to allow users to change default values without re-building the source code (as can be done with Application-scoped settings). However, the user shouldn't be forced to edit a .config file; they should also be able to make a change at run-time that persists across settings (as can be done with User-scoped settings). Surely there must be some sort of mechanism that provides both functionalities.
BOTTOM LINE: Why can't Application Settings (app.exe.config) be edited at Run-Time? That would solve all my problems. I understand that this could cause problems for users who share the same machine. But who does that anymore?
POTENTIAL WORKAROUND: Is there anyway to change the default storage location for the User Settings config file into a non-hidden folder?
UPDATE (for clarification):
What I'm saying is that I want to be able to change a default setting at Design-time, at Run-time, or in-between sessions (i.e., by editing a config file). But when using the built-in C# persistence mechanisms provided by Settings.settings, I must choose at most 2 out of the 3. Am I missing something? Is there another alternative that I am not aware of?
[Use Case: I want to store a "default" database name for the connection string, but I want the user to be able to specify a different database at runtime (and thereby become the "new" default for that user). But I also want to be able to over-write the default in the config file without re-running or re-building the application.]
[BETTER Use Case: (In response to comments)
I have a computational model with a config file that contains the default values for parameters in the model. User A starts up the model and decides to change the value of several of the parameters. That change needs to persist for all future sessions for that user (i.e., Edit at RunTime). Subsequently, that user wants to share that modified configuration file with his team (via version control repository, for example, or email). This would allow User B to update her default parameter values (to match User A's) without having to manually change them in the application (i.e., Edit Between Sessions). All of these mods should happen AFTER Design-Time.]
*I realize that I can "technically" edit user-scoped settings in the app.exe.config file located in the hidden AppData folder, but this is a hidden file and not all users may have sufficient privileges to view it. (BUT see "Potential Workaround" above.)

All you need to do is combine the two techniques!
At the start of a session, read the configured setting from a config file, and store it into a global static variable (or any form of persistence) that is writeable.
Then when a user decides to change this setting, simply change the value of the setting.
public static Program {
public static string ConnectionString { get; set; }
void Main(string connectionString) {
ConnectionString = connectionString;
}
}
public class SomeOtherClass {
public void SomeOtherMethod () {
Program.ConnectionString = "new value";
}
}
This is just a very trivial example of how you'd use this. Note that instead of passing the string as an argument to the program you'd probably choose to read the default value from the application settings. You'd also probably store the user-configured connectionstring into some sort of database so that for each user the database could be different.

What if you tried the following in the case study and you might generalize it?
As long as the user can change the default Database name, so this Key should be defined under the User Scope and not the Application scope
Upon installing the application which I assume a windows application, and on the first run, check if the user.config has the value of Database name, if yes proceed in loading the application, otherwise, move to step 3.
Show the user a screen with the database name has a default value and the user can change the settings and make sure to do some validations here, after finishing the settings page, store them in the user.config file, so your application on the next run, it will find the required settings in order to run normally.
For admin privileges, you can show a button to change the settings at run time.
I use this technique for all applications that needs from the user to define some important details like " where to store images, the database name , the connection string, ... etc"
hope this will give you a hint or something

Related

Settings not saved in Settins.settings

I'm using Settings.Settings to store settings at run-time. It was very helpful for my earlier application to store data. But in my current project its not saving the settings data. My application have some tab and each tab contains some TextBox. Im using textBox Text to store string values.
Properties.Settings.Default.Setting1 = textBox2.Text;
Properties.Settings.Default.Save();
It is a working method for my all previous application.But I can't understand why its not working in my current project.
Since your question does not include many details, I've tried to answer as much as possible:
Try to perform a Properties.Settings.Default.Upgrade() and then saved settings get loaded.
You have to call the Upgrade method of ApplicationSettingsBase derived class (that is normally called Settings and is created for you by Visual Studio)
Properties.Settings.Default.Upgrade();
When/where to call the Upgrade method? There is a simple trick you can apply: define a user setting called UpgradeRequired (example) as bool (the easiest way is through IDE). Make sure its default value is true.
Insert this code snipped at the start of the application:
if (Properties.Settings.Default.UpgradeRequired)
{
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.UpgradeRequired = false;
Properties.Settings.Default.Save();
}
So the Upgrade method will be called only after the version changes and only one time (since you disable further upgrades by setting UpgradeRequired = false until a version change - when the property regains default value of true).
Check the scope of your settings [USER/APPLICATION]
Try this out, and if it doesn't work check the below conditions.
Also, a more detailed question next time would be much appreciated.
Permission (NTFS permission)
Or Active directory permission
Or capacity of windows drive is full.
Or there exist two or more user folders and you checked another.
For example: There are two or three folders, user.domain, user.workgroupname, user.
Despite all this, I suggest you to learn about System.Reflection and develop your personalized method to save settings, the option provided by the Visual Studio isn't very dependable.
Hope this was helpful.

WPF Properties.Settings saving and multiple users

In my applications there are some setting saved in the Properties.Settings.Default. These settings can be changed by the user(s) and needs to be saved locally on the computer. While I can save these setting, the problem is that it is only saved for the user currently logged in. Once an user changes a setting it has to be for all users of the computer. How can I accomplish this?
User scoped settings are just that, settings that an individual user can change and will only be saved for that user.
The application scoped settings will affect all users but they are not designed to be changed by a user.
You might want to consider a different approach to storing settings that you want users to be able to change but to affect all users of an application e.g. the Windows registry or an external xml file.
Another option is to use user scoped settings but to change the location to a centralised location so that all users use/save the same settings. See Store user settings into application folder for an option on how to do this.
When you open the Settings Designer window in Visual Studio, you have four values that you need to enter for each setting:
You need to set the Scope property to Application to have a setting that is the same for all users. For the full story, read the Using Application Settings and User Settings page on MSDN.
Application settings cannot be changed, only by hand before the application is run so I do not recommend that approach.
In my opinion, propagating the changes may be generally a bad approach. Since this config (user.config) is generally stored in the user's own folder (under Users), it should not be modified by another user (in fact, without administrator acces, another user cannot even access).
I might recommend using other places to store application specific settings: xml or config file near your application, or maybe the registry.
I would use an external Database for that Stuff...
But if you want it quick and simple just save it to a File on the Harddrive (for example C:\Program_Data\\settings.csv) i would use a csv file because it's not much work...

How can I save form settings?

I was just wondering if anyone has any input on how to save a C# Winform setting?
Currently, I have a form that has various radio buttons, directory browsers, date pickers etc. I was wondering what is the best strategy to save these settings to an external file that can be loaded at a later date. So essentially each configuration can be loaded, executed, and then another configuration loaded. Also, the configuration can be passed across installations / users.
Application-scope settings are read only, and can only be changed at design time or by altering the .exe.config file in between application sessions. User-scope settings, however, can be written at run time, just as you would change any property value. The new value persists for the duration of the application session. You can persist changes to user settings between application sessions by calling the Settings.Save method. These settings are saved in the User.config file.
Write and Persist User Settings at Run Time
Access the user setting and assign it a new value, as shown in the following example:
Properties.Settings.Default.myColor = Color.UserGreen;
If you want to persist changes to user settings between application sessions, call the Save method, as shown in the following code:
Properties.Settings.Default.Save();
I solved this problem with a class or struct which contains all settings. My form-class had a constructor which accepted such a setting-instance.
This settings-class/-struct was implementing ISerializable. So you can save it easily into files and load it from.
This is by far not the best way to do it, but it is quiet easy to implement.

c# default variables? Settings.Defaullt,defaultCity=txtcity.text; how to do them?

Well i downloaded a program for wheater but it is not mind now, i watched, than you write a city and you close the program, and when you open it again, it has de last city you write, how is it? i watched it has this code in whaterform_formClosed
but how do i create these variables? and if this is posible can I to do a program without a database? saveing all in a dataset? or datatables? default databales? default dataset?
but now i want to know how to create a Default variable
private void weatherForm_FormClosed(object sender, FormClosedEventArgs e)
{
//Save Settings
Settings.Default.defaultCity = txtCity.Text;
Settings.Default.intervalText = comboBoxEdit1.Text;
Settings.Default.windowPosition = this.Location;
Settings.Default.timerOn = timer1.Enabled;
Settings.Default.intervalTime = delay;
Settings.Default.Save();
}
You can use 'settings' to do this:
Starting with the .NET Framework 2.0,
you can create and access values that
are persisted between application
execution sessions. These values are
called settings. Settings can
represent user preferences, or
valuable information the application
needs to use. For example, you might
create a series of settings that store
user preferences for the color scheme
of an application. Or you might store
the connection string that specifies a
database that your application uses.
Settings allow you to both persist
information that is critical to the
application outside the code, and to
create profiles that store the
preferences of individual users.
See Using Application Settings and User Settings for more information.
The easiest way to store information like this is in the config file (like it is in your example)
If you open the properties of your project, it contains a tab called settings. Add the properties that you want in there, make sure they have a scope of User and you should be able to do something very similar.

WPF/C#: Where should I be saving user preferences files?

What is the recommended location to save user preference files? Is there a recommended method for dealing with user preferences?
Currently I use the path returned from typeof(MyLibrary).Assembly.Location as a default location to store files generated or required by the application.
EDIT:
I found two related/interesting questions:
Best place to save user information for Windows XP and Vista applications
What's the way to implement Save / Load functionality?
EDIT #2:
This is just a note for people like me who had never used settings before.
Settings are pretty useful, but I had to do a whole bunch of digging to figure out what was going on (coming from the Python world, not something I am used too). Things got complicated as I wanted to save dictionaries and apparently they can't be serialized. Settings also seem to get stored in 3 different files depending on what you do. There is an app.config, user.config and a settings.setting file. So here are two more links that I found useful:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ddeaca86-a093-4997-82c9-01bc0c630138
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/efe370dc-f933-4e55-adf7-3cd8063949b0/
You can use the Application Settings easily enough.
If you haven't done so before just right click on the project and choose Properties. Select the Settings tab. Make sure you chose "User" for the scope (otherwise the setting is read-only).
The code to access this is simple:
forms.Width = Application1.Properties.Settings.Default.Width;
If you need to save it:
Application1.Properties.Settings.Default.Width = forms.Width;
Application1.Properties.Settings.Default.Save();
In the sample above, Width is the custom setting name you define in the Settings tab and Application1 is the Namespace of your application.
Edit: Responding to further questions
You mentioned you wanted to store Dictionary objects in the Settings. As you discovered, you can't do this directly because Dictionary objects are not serializable. However, you can create your own serializable dictionary pretty easily. Paul Welzer had an excellent example on his blog.
You have a couple of links which sort of muddy the situation a little. Your original question is where to save "User Preference Files". I'm pretty certain Microsoft's intention with the Settings functionality is exactly that... storing user skin preferences, layout choices, etc. It not meant as a generic repository for an application's data although it could be easily abused that way.
The data is stored in separate places for a good reason. Some of the settings are Application settings and are read-only. These are settings which the app needs to function but is not specific to a user (for example, URIs to app resources or maybe a tax rate). These are stored in the app.config.
User settings are stored in an obfuscated directory deep within the User Document/Settings folder. The defaults are stored in app.config (I think, can't recall for certain off the top of my head) but any user changes are stored in their personal folder. This is meant for data that changes from user to user. (By "user" I mean Windows user, not your app's user.)
Hope this clarified this somewhat for you. The system is actually pretty simple. It might seem a little foreign at first but after a few days of using it you'll never have to think of it again... it just works.
When running as non-admin or on Vista you can't write to the "Program files" folder (or any sub folder of it).
The correct location to store user preference is (replace MyCompanyName and MyApplicationName with the correct names, obviously)
On disk:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\MyCompanyName\\MyApplicationName"
Or in the registry under the key:
HKEY_CURRENT_USER\Software\MyCompanyName\MyApplicationName
Those location are per-user and they work with non-admin user, several users using the same computer, fast user switching, terminal services and all the other ways people can interact with your software.
If you need a common location for all users then:
It will only work when the user run as an administrator
It will not work reliably on Vista
You have to take care of everything yourself (like two users running the application on the same computer at the same time via fast user switching).
and the locations are:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationCommonData) + "\\MyCompanyName\\MyApplicationName"
Or in the registry under the key:
HKEY_LOCAL_MACHINE\Software\MyCompanyName\MyApplicationName
You can use isolated storage. You can isolate by user, assembly and/or domain.
Introduction to Isolated Storage
http://msdn.microsoft.com/en-us/library/3ak841sy(VS.80).aspx
Types of Isolation
http://msdn.microsoft.com/en-us/library/eh5d60e1(VS.80).aspx
the following seems to be the best option:
Application.UserAppDataPath

Categories