views:

1498

answers:

2

Is there any supported API in .NET 2.0 for writing to the userSettings section of the main exe's .config file?

The scenario is:

Winforms 2.0 application.

I have a setting (a database connection string, if you need to know) that has user level scope. This means that each user has a user.config file created by .net when the user saves the value of the setting.

For new users that run the application for the first time, the main exe's .config file of the application contains a default value in the user settings section. This section is created by visual studio when the setting is created in the Settings tab of the project properties.

Now, I want to allow any Administrator user in the computer to be able to change the default value for new users. Only Administrators will have this option, because regular users don't have permission to write to the main exe's .config file anyway.

I have found how to write user settings to the user's .config file, and how to write to the appSettings section of the main .config file. But my googling has failed when trying to find out how to write to the userSettings section of the main .config

Is my only chance failing back to System.Xml and do it manually loading the .config in an XmlDocument?

+1  A: 

I think yes - manually writing to the .config file is the only way. Or you can let the administrator edit the .config-file himself.

CKoenig
In this case, the administrator is not a computer savvy person. It is just a user that happens to be running as Admin in his machine (for instance, almost any home XP user). But your suggestion could be useful in a different scenario. thanks.
Sergio Acosta
+1  A: 

After some research I came up with this solution. It is a bit low level, but still goes through the .NET configuration API without having to manually parse the .config file.

static void SaveUserSettingDefault(string clientSectionName, string settingName, object settingValue)
{
    System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    // find section group
    ConfigurationSectionGroup group = config.SectionGroups[@"userSettings"];
    if (group == null) return;

    // find client section
    ClientSettingsSection clientSection = group.Sections[clientSectionName] as ClientSettingsSection;
    if (clientSection == null) return;

    // find setting element
    SettingElement settingElement = null;
    foreach (SettingElement s in clientSection.Settings)
    {
        if (s.Name == settingName)
        {
            settingElement = s;
            break;
        }
    }
    if (settingElement == null) return;

    // remove the current value
    clientSection.Settings.Remove(settingElement);

    // change the value
    settingElement.Value.ValueXml.InnerText = settingValue.ToString();

    // add the setting
    clientSection.Settings.Add(settingElement);

    // save changes
    config.Save(ConfigurationSaveMode.Full);
}

Given a .config with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyAssembly.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <userSettings>
        <MyAssembly.Properties.Settings>
            <setting name="SqlConnectionString" serializeAs="String">
                <value>Server=(local);Database=myDatabase;Integrated Security=true;</value>
            </setting>
        </MyAssembly.Properties.Settings>
    </userSettings>
</configuration>

You would use it like this:

if (RunningAsAdmin) // save value in main exe's config file
{
    SaveUserSettingDefault(@"MyAssembly.Properties.Settings", @"SQLConnectionString", theNewConnectionString);
}
else // save setting in user's config file
{
    Settings.Default. SQLConnectionString = theNewConnectionString;
    Settings.Default.Save();
}
Sergio Acosta