15

What use are they if they cannot be altered from their default values anyway? Rhetorical question.

First, what's the best way to circumvent the Settings system and write to the application scope settings file directly (security issues in the next paragraph)? XmlReader/XmlWriter?

IIRC, if an application tries to write to its Program Files folder, Windows Vista and 7 does some magic to prevent that. I suppose I need to call UAC to elevate and I must put that fancy shield icon on my application's Options window's OK button and so on. Link to a quick how-to?

Alternatively, you may tell me that what I'm trying to do is stupid and I should store my alterable application scope settings somewhere else altogether.

CannibalSmith
  • 4,742
  • 10
  • 44
  • 52

3 Answers3

14

If you change them to "user" settings they can be changed in code, and when you call Save() they will be saved to a user.config file in the current users local settings folder.

Obviously, this means they can be different for every user. Generally, global application settings that are the same for every user aren't modified in code because a change that one user makes will effect everyone else (hence the app settings are read only).

If you don't want them to be user scoped, take a look at the ConfigurationManager class. This will allow you to manually read and write to .config files. Remember though that the c:\program files\ folder is protected and normal users won't have access to it (this will result in UAC prompts or failure in vista/win7). Consider carefully how you will handle it, and remember that any change to an app.config will affect all users.

There is no location in windows that all users are guaranteed to have write access to.

Simon P Stevens
  • 27,303
  • 5
  • 81
  • 107
  • 2
    But that is exactly what I want! User A modifies something, and User B doesn't have to repeat that modification. – CannibalSmith Nov 06 '09 at 12:56
  • 10
    It's strange to me that more people don't need this feature. Surely lots of applications have global settings that the programmer wants to build a friendly UI for. – Ben Mills Apr 20 '11 at 20:44
  • 1
    @Ben - You can use the [ConfigurationManager](http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx) class if you really do want to save settings directly to the global .exe.config file. Obviously, if that file is in c:\programfiles\ your user will need the appropriate admin permissions. First open the config like this: var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); then add your new setting like this: config.AppSettings.Settings.Add("key", "value"); (Or you can create custom config sections) Don't forget to call save. – Simon P Stevens Apr 21 '11 at 08:06
  • What about installing the app to something other than "Program Files" so that the write permission isn't an issue? Are there any problems with this approach? – PIntag Aug 08 '12 at 23:08
  • Are the settings in the ConfigurationMangager the same as in the .settings file in my VS2010 project? I don't see those settings in the ConfigurationManager. I used the code that Simon P Stevens posted. – OneWorld Jan 22 '13 at 10:52
  • (Answer to my comment:) Have a look at config.FilePath. This is the xml file where the changes get saved. There are several tags. The code Simon P Stevens provided saves its stuff in -Tag. However, the stuff from the .settings file of the VS2010 project is saved in I managed to read those values through the ConfigurationManger class, but not to manipulate them. This is how u read them: `ConfigurationElementCollection applicationSettings = confog.SectionGroups["applicationSettings"].Sections[.Properties.Settings"].ElementInformation.Properties;` – OneWorld Jan 22 '13 at 12:46
  • What is that Application Scope usefulness if it is only for reading?? What's the difference between it compared to some static public read-only variable! – Beyondo Jul 27 '19 at 10:25
2

An old question, but I provide this answer to help anyone attempting to implement Simon P Stevens' answer related to the ConfigurationManager class since I wasn't sure how to do it being a novice with settings.

One of the first realizations was that the 2 Settings files in my C# project (made difficult because the typical one under Properties was there, but empty) were combined into the single .config and split between different ConfigurationSections. I thought that was why ConfigurationManager.AppSettings and ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) both kept returning 0 keys.

It took a lot of trial and error to realize that most of the ConfigurationManager references deal with the default appSettings and that was different than applicationSettings which is what Settings uses.

I ultimately found the following:

Select the right ConfigurationSectionGroup/ConfigurationSectionClient, cast to SettingsSection, get the setting, and set the XML InnerText (e.g. below):

// this gets the applicationSettings section (and the inner section 'inoBIBooks.My.MySettings')
Configuration config = WebConfigurationManager.OpenWebConfiguration("/" + targetvdir);
ConfigurationSectionGroup applicationSectionGroup = config.GetSectionGroup("applicationSettings");
ConfigurationSection applicationConfigSection = 
applicationSectionGroup.Sections["inoBIBooks.My.MySettings"];
ClientSettingsSection clientSection = (ClientSettingsSection)applicationConfigSection;

// set a value to that specific property
SettingElement applicationSetting = clientSection.Settings.Get("BIDB_Username");
applicationSetting.Value.ValueXml.InnerText = "username";

// without this, saving won't work
applicationConfigSection.SectionInformation.ForceSave = true;
// save
config.Save();

This is pulled from:
Access section 'applicationSettings' (not 'appSettings') in config file from setup
and
Save and reload app.config(applicationSettings) at runtime

pigeon
  • 151
  • 9
1

Look here: Best practice to save application settings in a Windows Forms Application

The ApplicationSettings class doesn't support saving settings to the app.config file. That's very much by design, apps that run with a properly secured user account (think Vista UAC) do not have write access to the program's installation folder.

You can fight the system with the ConfigurationManager class. But the trivial workaround is to go into the Settings designer and change the setting's scope to User. If that causes hardships (say, the setting is relevant to every user), you should put your Options feature in a separate program so you can ask for the privilege elevation prompt. Or forego using a setting.

Community
  • 1
  • 1
bitbonk
  • 48,890
  • 37
  • 186
  • 278