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...
Related
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.
We have a C#.Net application which uses a network database. I mean to say that many instances of the application will access the same db from different machines. So if I have to store the user-id to show the user while re-logging in, where can I store it?
The options i have are:
- Storing it in a local file in application directory. (But the problem is that the application is installed using Click Once. When the application is updated the application directory is being changed. May be I am missing something here.)
- Storing in the registry. Are there any other?
Can some one please suggest what to do? Correct me if I am wrong.
There are buil-int locations for this kind of stuff see Environment - specifically:
ApplicationData (user-specific roaming)
LocalApplicationData (user-specific non-roaming)
CommonApplicationData (not user-specific)
Generally you want to store any data that needs to persist between sessions, and is user specific in the registry, or the user AppData folder. Normally for small things (i.e. ids, basic settings etc....) the registry is the best place. Just make sure to stick it under HKCU\Software\Your company name\your program name. Although if the data is sensitive you should be careful where you place it, and it should be encryptedto protect it from basic snooping. If it's data that isn't sensitive though then the registry is a good place to put it.
This assumes of course that the installation and configuration doesn't need to be xcopy portable (i.e. a user could just copy the installation folder to a new place/computer and have everything work as normal). If that's the case then you'll want to store it under the installation directory.
If you need to store the UserID on the local, keep it in some kind of configuration file, mabe under a "LastLogin" entry. Check out this question and specifically this answer for more information.
Consider using Isolated Storage
I want to get and set some application settings hidden for the user. In this case these are two tokens and two tokens that are being altered by the application. But still all four them are a secret to the application user.
I found two ways on MSDN and this forum.
Use a .config file. -> this sounds okay and I can change some values in it. But I see still a plain text file after publish.
Use the settings in the project properties. -> should it be? I read warnings about that this not so secure after all.
A lot of sites describe a web server solution while I just want to have a desktop solution.
Btw. It is not a commercial product, I am making a hobby project to learn more from C#.net.
If these files need to be altered by the application, you will need to persist these outside of the application so that the new settings will be loaded next time the app starts.
For this, you can always create a config (or settings) file and hide it in the System.IO.IsolatedStorage files for the assembly. This is still editable by the user, but its a bit of a pain to find - plus this will transfer over with roaming profiles so that the settings are used cross machine.
Something simple to help you start out:
IsolatedStorage.IsolatedStorageFile storage = IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly();
string subdirectory = "SomeDirectory";
storage.CreateFile(System.IO.Path.Combine(subdirectory, "settings.config"));
Does the * existence* of the setting need to be kept secret, or just its value?
If the latter, I'd suggest encrypting the value you save to the .config file.
I want to know what is the actual difference between Application and User scope in Settings configuration for vs projects.
Is the only difference the fact that if I select Application, I can't use Settings.MyProperty as a setter, but I have to use Settings["MyProperty"] instead?
How would using the User scope affect the program otherwise, if the config file is located at my application root?
User scope means each user gets their own copy, the settings are stored in the users profile folders and your App can Save those settings without Admin privileges.
If you change an Application setting (using Settings["MyProperty"]) and call Settings.Save() you will have to be running as Admin because the changes are saved to MyApplication.exe.config . And changes apply to all users.
Your best bet is to use the 'User' setting because with the newer operating systems Windows doesn't like you reading and writing to files that are local to your executable, this looks suspicious due to the awareness of viruses. So Windows likes you to read and write to designated safe areas which I believe happens in some application data area that the operating system keeps track of. If you set the scope to 'Application' it may try to write this data to the local config file(which is why you need to run with admin privileges) and with the operating systems becoming more locked down there may still be issues doing this. Your app may work in XP like this but anything newer might not work, especially when apps run in the 'c:\Program Files' folders...
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