Search code examples
.netapplication-settings

share writable settings between users


I'd like to use the .NET settings designer/framework to create application settings at design time and have these settings writeable by the application at runtime. It seems out of the box I can't create settings that can be changed by the application and that are read by all users when they run the the application?

I have code that only allows one instance of the application across all users so conflict is not an issue.

So far I think I need to create a custom SettingsProvider. I'm hoping I can somehow inherit from LocalFileSettingsProvider and overwrite the file locations, but can't find a way to do this.


Solution

  • This is how I did it. Now all I need to kn ow is if I need to implement IApplicationSettingsProvider in order to successfully migrate settings between versions? Peer reviews and comments welcome!

    using System.Collections.Generic;
    using System.Configuration;
    using System.Windows.Forms;
    using System.Collections.Specialized;
    using System.IO.IsolatedStorage;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace NetworkManager
    {
        class IsolatedStorageSettingsProvider : SettingsProvider
        {
            public IsolatedStorageSettingsProvider()
            {
    
            }
    
            public override string ApplicationName
            {
                get { return Application.ProductName; }
                set { }
            }
    
            public override void Initialize(string name, NameValueCollection col)
            {
                base.Initialize(this.ApplicationName, col);
            }
    
            // SetPropertyValue is invoked when ApplicationSettingsBase.Save is called
            // ASB makes sure to pass each provider only the values marked for that provider -
            // though in this sample, since the entire settings class was marked with a SettingsProvider
            // attribute, all settings in that class map to this provider
            public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
            {
                // Iterate through the settings to be stored
                // Only IsDirty=true properties should be included in propvals
                foreach (SettingsPropertyValue propval in propvals)
                {
    
                    SetSettingValue(propval.Name, propval.SerializedValue);
                }
            }
    
            public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
            {
    
                // Create new collection of values
                SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
    
                // Iterate through the settings to be retrieved
                foreach (SettingsProperty setting in props)
                {
                    SettingsPropertyValue value = new SettingsPropertyValue(setting);
                    value.IsDirty = false;
                    value.SerializedValue = GetSettingValue(setting);
                    values.Add(value);
                }
                return values;
            }
    
            private IsolatedStorageFile GetStore()
            {
                return IsolatedStorageFile.GetStore( IsolatedStorageScope.Machine | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null);
            }
    
            private object GetSettingValue(SettingsProperty setting)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                var settings = new Dictionary<string, object>();
                var store = GetStore();
                using (var stream = store.OpenFile("settings.cfg", FileMode.OpenOrCreate, FileAccess.Read))
                {
                    if (stream.Length > 0) settings = (Dictionary<string, object>)formatter.Deserialize(stream);
                }
                return (settings.ContainsKey(setting.Name)) ? settings[setting.Name] : null;
            }
    
            private void SetSettingValue(string name, object value)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                var settings = new Dictionary<string, object>();
                var store = GetStore();
                using (var stream = store.OpenFile("settings.cfg", FileMode.OpenOrCreate, FileAccess.Read))
                {
                    if (stream.Length > 0) settings = (Dictionary<string, object>)formatter.Deserialize(stream);
                }
                settings[name] = value;
                using (var stream = store.OpenFile("settings.cfg", FileMode.OpenOrCreate, FileAccess.Write))
                {
                    formatter.Serialize(stream, settings);
                }
                return ;
            }
    
        }
    }