12 internal class RegistrySettingsProvider : SettingsProvider
15 private const string CompanyName =
"Analyze Re";
16 private const string SubKeyPath =
@"Software\" + CompanyName;
19 public override string ApplicationName {
get;
set; } = CompanyName;
20 public override string Name =>
"RegistrySettingsProvider";
21 public override string Description =>
"Analyze Re - shared registry settings provider";
24 private string _initializedName;
27 private NameValueCollection _initializedConfig;
29 public override void Initialize(
string name, NameValueCollection col)
31 _initializedName = name;
32 _initializedConfig = col;
33 base.Initialize(ApplicationName, col);
39 public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
42 foreach (SettingsPropertyValue propval
in propvals)
54 if (IsApplicationScoped(propval.Property))
59 Debug.Print($
"RegistrySettingsProvider.SetPropertyValues - Setting {propval.Name} to {propval.SerializedValue}");
60 using (RegistryKey
key = CreateRegKey(context, propval.Property))
63 if (propval.PropertyValue ==
null)
64 key.DeleteValue(propval.Name);
65 else if (propval.PropertyValue is StringCollection sc)
67 string[] stringArray =
new string[sc.Count];
68 sc.CopyTo(stringArray, 0);
69 key.SetValue(propval.Name, stringArray, RegistryValueKind.MultiString);
73 key.SetValue(propval.Name, propval.SerializedValue);
79 public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection properties)
81 if (!HasRegKey(context))
84 SettingsPropertyValueCollection localFileValues = GetLocalFilePropertyValues(context, properties);
87 foreach (SettingsPropertyValue value
in localFileValues)
89 if (!value.UsingDefaultValue &&
90 value.SerializedValue != value.Property.DefaultValue)
96 SetPropertyValues(context, localFileValues);
97 return localFileValues;
100 SettingsPropertyValueCollection values =
new SettingsPropertyValueCollection();
102 foreach (SettingsProperty prop
in properties)
104 SettingsPropertyValue value = GetPropertyValue(context, prop);
105 Debug.Assert(value !=
null);
112 private SettingsPropertyValue GetPropertyValue(SettingsContext context, SettingsProperty prop)
114 SettingsPropertyValue value =
new SettingsPropertyValue(prop);
119 if (IsUserScoped(prop))
121 using (RegistryKey
key = CreateRegKey(context, prop))
123 object regValue =
key.GetValue(prop.Name);
124 if (prop.PropertyType == typeof(StringCollection) &&
125 regValue is
string[] regValueStrings)
127 StringCollection stringCol =
new StringCollection();
128 stringCol.AddRange(regValueStrings);
129 value.PropertyValue = stringCol;
133 value.SerializedValue = regValue;
138 value.IsDirty =
false;
143 private bool IsApplicationScoped(SettingsProperty prop)
145 return HasSettingScope(prop, typeof(ApplicationScopedSettingAttribute));
149 private bool IsUserScoped(SettingsProperty prop)
151 return HasSettingScope(prop, typeof(UserScopedSettingAttribute));
157 private bool HasSettingScope(SettingsProperty prop, Type attributeType)
160 Debug.Assert(attributeType == typeof(ApplicationScopedSettingAttribute) ||
161 attributeType == typeof(UserScopedSettingAttribute));
162 bool isAppScoped = prop.Attributes[typeof(ApplicationScopedSettingAttribute)] !=
null;
163 bool isUserScoped = prop.Attributes[typeof(UserScopedSettingAttribute)] !=
null;
166 if (isUserScoped && isAppScoped)
167 throw new Exception(
"Can't mark a setting as User and Application-scoped: " + prop.Name);
168 if (!isUserScoped && !isAppScoped)
169 throw new Exception(
"Must mark a setting as User or Application-scoped: " + prop.Name);
172 if (attributeType == typeof(ApplicationScopedSettingAttribute))
174 if (attributeType == typeof(UserScopedSettingAttribute))
181 private bool HasRegKey(SettingsContext context)
183 RegistryKey
key = Registry.CurrentUser.OpenSubKey($
@"{SubKeyPath}\{GetSectionName(context)}",
false);
188 private RegistryKey CreateRegKey(SettingsContext context, SettingsProperty prop)
190 Debug.Assert(!IsApplicationScoped(prop),
"Can't get Registry key for a read-only Application scoped setting: " + prop.Name);
191 return Registry.CurrentUser.CreateSubKey($
@"{SubKeyPath}\{GetSectionName(context)}");