2 // CustomizableFileSettingsProvider.cs
5 // Noriaki Okimoto <seara@ojk.sppd.ne.jp>
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // (C)2007 Noriaki Okimoto
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 extern alias PrebuiltSystem;
35 using System.Collections;
36 using System.Collections.Generic;
37 using System.Configuration;
38 using System.Globalization;
40 using System.Reflection;
41 using System.Security.Cryptography;
45 using NameValueCollection = PrebuiltSystem.System.Collections.Specialized.NameValueCollection;
47 namespace System.Configuration
49 // location to store user configuration settings.
50 internal enum UserConfigLocationOption : uint
53 Product_VersionMajor = 0x21,
54 Product_VersionMinor = 0x22,
55 Product_VersionBuild = 0x24,
56 Product_VersionRevision = 0x28,
57 Company_Product = 0x30,
58 Company_Product_VersionMajor = 0x31,
59 Company_Product_VersionMinor = 0x32,
60 Company_Product_VersionBuild = 0x34,
61 Company_Product_VersionRevision = 0x38,
66 internal class CustomizableFileSettingsProvider : SettingsProvider, IApplicationSettingsProvider
70 // This is used from within System.Web to allow mapping of the ExeConfigFilename to
71 // the correct Web.config for the current request. Otherwise web applications will
72 // not be able to access settings from Web.config. The type assigned to this
73 // variable must descend from the ConfigurationFileMap class and its
74 // MachineConfigFilename will be used to set the ExeConfigFilename.
76 // This is necessary to fix bug #491531
77 #pragma warning disable 649
78 private static Type webConfigurationFileMapType;
79 #pragma warning restore 649
81 private static string userRoamingPath = "";
82 private static string userLocalPath = "";
83 private static string userRoamingPathPrevVersion = "";
84 private static string userLocalPathPrevVersion = "";
85 private static string userRoamingName = "user.config";
86 private static string userLocalName = "user.config";
87 private static string userRoamingBasePath = "";
88 private static string userLocalBasePath = "";
89 private static string CompanyName = "";
90 private static string ProductName = "";
91 private static string ForceVersion = "";
92 private static string[] ProductVersion;
94 // whether to include parts in the folder name or not:
95 private static bool isVersionMajor = false; // 0x0001 major version
96 private static bool isVersionMinor = false; // 0x0002 minor version
97 private static bool isVersionBuild = false; // 0x0004 build version
98 private static bool isVersionRevision = false; // 0x0008 revision
99 private static bool isCompany = true; // 0x0010 corporate name
100 private static bool isProduct = true; // 0x0020 product name
101 private static bool isEvidence = false; // 0x0040 evidence hash
103 private static bool userDefine = false; // 0x8000 ignore all above and use user definition
105 private static UserConfigLocationOption userConfig = UserConfigLocationOption.Company_Product;
107 public override void Initialize (string name, NameValueCollection config)
109 base.Initialize (name, config);
112 // full path to roaming user.config
113 internal static string UserRoamingFullPath {
114 get { return Path.Combine (userRoamingPath, userRoamingName); }
117 // full path to local user.config
118 internal static string UserLocalFullPath {
119 get { return Path.Combine (userLocalPath, userLocalName); }
122 // previous full path to roaming user.config
123 public static string PrevUserRoamingFullPath {
124 get { return Path.Combine (userRoamingPathPrevVersion, userRoamingName); }
127 // previous full path to local user.config
128 public static string PrevUserLocalFullPath {
129 get { return Path.Combine (userLocalPathPrevVersion, userLocalName); }
132 // path to roaming user.config
133 public static string UserRoamingPath {
134 get { return userRoamingPath; }
137 // path to local user.config
138 public static string UserLocalPath {
139 get { return userLocalPath; }
142 // file name which is equivalent to user.config, for roaming user
143 public static string UserRoamingName {
144 get { return userRoamingName; }
147 // file name which is equivalent to user.config, for local user
148 public static string UserLocalName {
149 get { return userLocalName; }
152 public static UserConfigLocationOption UserConfigSelector
154 get { return userConfig; }
158 if (((uint) userConfig & 0x8000) != 0) {
159 isVersionMajor = false;
160 isVersionMinor = false;
161 isVersionBuild = false;
162 isVersionRevision = false;
167 isVersionRevision = ((uint) userConfig & 0x0008) != 0;
168 isVersionBuild = isVersionRevision | ((uint)userConfig & 0x0004) != 0;
169 isVersionMinor = isVersionBuild | ((uint)userConfig & 0x0002) != 0;
170 isVersionMajor = IsVersionMinor | ((uint)userConfig & 0x0001) != 0;
172 isCompany = ((uint) userConfig & 0x0010) != 0;
173 isProduct = ((uint) userConfig & 0x0020) != 0;
177 // whether the path to include the major version.
178 public static bool IsVersionMajor
180 get { return isVersionMajor; }
183 isVersionMajor = value;
184 isVersionMinor = false;
185 isVersionBuild = false;
186 isVersionRevision = false;
190 // whether the path to include minor version.
191 public static bool IsVersionMinor
193 get { return isVersionMinor; }
196 isVersionMinor = value;
198 isVersionMajor = true;
199 isVersionBuild = false;
200 isVersionRevision = false;
204 // whether the path to include build version.
205 public static bool IsVersionBuild
207 get { return isVersionBuild; }
210 isVersionBuild = value;
211 if (isVersionBuild) {
212 isVersionMajor = true;
213 isVersionMinor = true;
215 isVersionRevision = false;
219 // whether the path to include revision.
220 public static bool IsVersionRevision
222 get { return isVersionRevision; }
225 isVersionRevision = value;
226 if (isVersionRevision) {
227 isVersionMajor = true;
228 isVersionMinor = true;
229 isVersionBuild = true;
234 // whether the path to include company name.
235 public static bool IsCompany
237 get { return isCompany; }
238 set { isCompany = value; }
241 // whether the path to include evidence hash.
242 public static bool IsEvidence
244 get { return isEvidence; }
245 set { isEvidence = value; }
248 // AssemblyCompanyAttribute->Namespace->"Program"
249 private static string GetCompanyName ()
251 Assembly assembly = Assembly.GetEntryAssembly ();
252 if (assembly == null)
253 assembly = Assembly.GetCallingAssembly ();
255 AssemblyCompanyAttribute [] attrs = (AssemblyCompanyAttribute []) assembly.GetCustomAttributes (typeof (AssemblyCompanyAttribute), true);
257 if ((attrs != null) && attrs.Length > 0) {
258 return attrs [0].Company;
261 MethodInfo entryPoint = assembly.EntryPoint;
262 Type entryType = entryPoint != null ? entryPoint.DeclaringType : null;
263 if (entryType != null && !String.IsNullOrEmpty (entryType.Namespace)) {
264 int end = entryType.Namespace.IndexOf ('.');
265 return end < 0 ? entryType.Namespace : entryType.Namespace.Substring (0, end);
270 private static string GetProductName ()
272 Assembly assembly = Assembly.GetEntryAssembly ();
273 if (assembly == null)
274 assembly = Assembly.GetCallingAssembly ();
276 byte [] pkt = assembly.GetName ().GetPublicKeyToken ();
277 return String.Format ("{0}_{1}_{2}",
278 AppDomain.CurrentDomain.FriendlyName,
279 pkt != null && pkt.Length > 0 ? "StrongName" : "Url",
283 // Note: Changed from base64() to hex output to avoid unexpected chars like '\' or '/' with filesystem meaning.
284 // Otherwise eventually filenames, which are invalid on linux or windows, might be created.
285 // Signed-off-by: Carsten Schlote <schlote@vahanus.net>
286 // TODO: Compare with .NET. It might be also, that their way isn't suitable for Unix OS derivates (slahes in output)
287 private static string GetEvidenceHash ()
289 Assembly assembly = Assembly.GetEntryAssembly ();
290 if (assembly == null)
291 assembly = Assembly.GetCallingAssembly ();
293 byte [] pkt = assembly.GetName ().GetPublicKeyToken ();
294 byte [] hash = SHA1.Create ().ComputeHash (pkt != null && pkt.Length >0 ? pkt : Encoding.UTF8.GetBytes (assembly.EscapedCodeBase));
295 System.Text.StringBuilder evidence_string = new System.Text.StringBuilder();
296 foreach (byte b in hash)
297 evidence_string.AppendFormat("{0:x2}",b);
298 return evidence_string.ToString ();
301 private static string GetProductVersion ()
303 Assembly assembly = Assembly.GetEntryAssembly ();
304 if (assembly == null)
305 assembly = Assembly.GetCallingAssembly ();
306 if (assembly == null)
309 return assembly.GetName ().Version.ToString ();
312 private static void CreateUserConfigPath ()
317 if (ProductName == "")
318 ProductName = GetProductName ();
319 if (CompanyName == "")
320 CompanyName = GetCompanyName ();
321 if (ForceVersion == "")
322 ProductVersion = GetProductVersion ().Split('.');
324 // C:\Documents and Settings\(user)\Application Data
325 if (userRoamingBasePath == "")
326 userRoamingPath = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
328 userRoamingPath = userRoamingBasePath;
330 // C:\Documents and Settings\(user)\Local Settings\Application Data (on Windows)
331 if (userLocalBasePath == "")
332 userLocalPath = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
334 userLocalPath = userLocalBasePath;
337 userRoamingPath = Path.Combine (userRoamingPath, CompanyName);
338 userLocalPath = Path.Combine (userLocalPath, CompanyName);
343 Assembly assembly = Assembly.GetEntryAssembly ();
344 if (assembly == null)
345 assembly = Assembly.GetCallingAssembly ();
346 byte [] pkt = assembly.GetName ().GetPublicKeyToken ();
347 ProductName = String.Format ("{0}_{1}_{2}",
349 pkt != null ? "StrongName" : "Url",
352 userRoamingPath = Path.Combine (userRoamingPath, ProductName);
353 userLocalPath = Path.Combine (userLocalPath, ProductName);
359 if (ForceVersion == "") {
360 if (isVersionRevision)
361 versionName = String.Format ("{0}.{1}.{2}.{3}", ProductVersion [0], ProductVersion [1], ProductVersion [2], ProductVersion [3]);
362 else if (isVersionBuild)
363 versionName = String.Format ("{0}.{1}.{2}", ProductVersion [0], ProductVersion [1], ProductVersion [2]);
364 else if (isVersionMinor)
365 versionName = String.Format ("{0}.{1}", ProductVersion [0], ProductVersion [1]);
366 else if (isVersionMajor)
367 versionName = ProductVersion [0];
372 versionName = ForceVersion;
374 string prevVersionRoaming = PrevVersionPath (userRoamingPath, versionName);
375 string prevVersionLocal = PrevVersionPath (userLocalPath, versionName);
377 userRoamingPath = Path.Combine (userRoamingPath, versionName);
378 userLocalPath = Path.Combine (userLocalPath, versionName);
379 if (prevVersionRoaming != "")
380 userRoamingPathPrevVersion = Path.Combine(userRoamingPath, prevVersionRoaming);
381 if (prevVersionLocal != "")
382 userLocalPathPrevVersion = Path.Combine(userLocalPath, prevVersionLocal);
385 // string for the previous version. It ignores newer ones.
386 private static string PrevVersionPath (string dirName, string currentVersion)
388 string prevVersionString = "";
390 if (!Directory.Exists(dirName))
391 return prevVersionString;
392 DirectoryInfo currentDir = new DirectoryInfo (dirName);
393 foreach (DirectoryInfo dirInfo in currentDir.GetDirectories ())
394 if (String.Compare (currentVersion, dirInfo.Name, StringComparison.Ordinal) > 0)
395 if (String.Compare (prevVersionString, dirInfo.Name, StringComparison.Ordinal) < 0)
396 prevVersionString = dirInfo.Name;
398 return prevVersionString;
401 // sets the explicit path to store roaming user.config or equivalent.
402 // (returns the path validity.)
403 public static bool SetUserRoamingPath (string configPath)
405 if (CheckPath (configPath))
407 userRoamingBasePath = configPath;
414 // sets the explicit path to store local user.config or equivalent.
415 // (returns the path validity.)
416 public static bool SetUserLocalPath (string configPath)
418 if (CheckPath (configPath))
420 userLocalBasePath = configPath;
427 private static bool CheckFileName (string configFile)
430 char[] invalidFileChars = Path.GetInvalidFileNameChars();
432 foreach (char invalidChar in invalidFileChars)
434 if (configFile.Contains(invalidChar.ToString()))
441 return configFile.IndexOfAny (Path.GetInvalidFileNameChars ()) < 0;
444 // sets the explicit roaming file name which is user.config equivalent.
445 // (returns the file name validity.)
446 public static bool SetUserRoamingFileName (string configFile)
448 if (CheckFileName (configFile))
450 userRoamingName = configFile;
457 // sets the explicit local file name which is user.config equivalent.
458 // (returns the file name validity.)
459 public static bool SetUserLocalFileName (string configFile)
461 if (CheckFileName (configFile))
463 userLocalName = configFile;
470 // sets the explicit company name for folder.
471 // (returns the file name validity.)
472 public static bool SetCompanyName (string companyName)
474 if (CheckFileName (companyName))
476 CompanyName = companyName;
483 // sets the explicit product name for folder.
484 // (returns the file name validity.)
485 public static bool SetProductName (string productName)
487 if (CheckFileName (productName))
489 ProductName = productName;
496 // sets the explicit major version for folder.
497 public static bool SetVersion (int major)
499 ForceVersion = string.Format ("{0}", major);
503 // sets the explicit major and minor versions for folder.
504 public static bool SetVersion (int major, int minor)
506 ForceVersion = string.Format ("{0}.{1}", major, minor);
510 // sets the explicit major/minor/build numbers for folder.
511 public static bool SetVersion (int major, int minor, int build)
513 ForceVersion = string.Format ("{0}.{1}.{2}", major, minor, build);
517 // sets the explicit major/minor/build/revision numbers for folder.
518 public static bool SetVersion (int major, int minor, int build, int revision)
520 ForceVersion = string.Format ("{0}.{1}.{2}.{3}", major, minor, build, revision);
524 // sets the explicit version number string for folder.
525 public static bool SetVersion (string forceVersion)
527 if (CheckFileName (forceVersion))
529 ForceVersion = forceVersion;
536 private static bool CheckPath (string configPath)
538 char[] invalidPathChars = Path.GetInvalidPathChars ();
541 foreach (char invalidChar in invalidPathChars)
543 if (configPath.Contains (invalidChar.ToString()))
549 if (configPath.IndexOfAny (invalidPathChars) >= 0)
552 string folder = configPath;
554 while ((fileName = Path.GetFileName (folder)) != "")
556 if (!CheckFileName (fileName))
560 folder = Path.GetDirectoryName (folder);
567 public override string Name {
568 get { return base.Name; }
571 string app_name = String.Empty;//"OJK.CustomSetting.CustomizableLocalFileSettingsProvider";
572 public override string ApplicationName {
573 get { return app_name; }
574 set { app_name = value; }
577 private ExeConfigurationFileMap exeMapCurrent = null;
578 private ExeConfigurationFileMap exeMapPrev = null;
579 private SettingsPropertyValueCollection values = null;
582 /// Hack to remove the XmlDeclaration that the XmlSerializer adds.
584 /// see <a href="https://github.com/mono/mono/pull/2273">Issue 2273</a> for details
586 private string StripXmlHeader (string serializedValue)
588 if (serializedValue == null)
593 XmlDocument doc = new XmlDocument ();
594 XmlElement valueXml = doc.CreateElement ("value");
595 valueXml.InnerXml = serializedValue;
597 foreach (XmlNode child in valueXml.ChildNodes) {
598 if (child.NodeType == XmlNodeType.XmlDeclaration) {
599 valueXml.RemoveChild (child);
604 // InnerXml will give you well-formed XML that you could save as a separate document, and
605 // InnerText will immediately give you a pure-text representation of this inner XML.
606 return valueXml.InnerXml;
609 private void SaveProperties (ExeConfigurationFileMap exeMap, SettingsPropertyValueCollection collection, ConfigurationUserLevel level, SettingsContext context, bool checkUserLevel)
611 Configuration config = ConfigurationManager.OpenMappedExeConfiguration (exeMap, level);
613 UserSettingsGroup userGroup = config.GetSectionGroup ("userSettings") as UserSettingsGroup;
614 bool isRoaming = (level == ConfigurationUserLevel.PerUserRoaming);
616 if (userGroup == null) {
617 userGroup = new UserSettingsGroup ();
618 config.SectionGroups.Add ("userSettings", userGroup);
620 ApplicationSettingsBase asb = context.CurrentSettings;
621 string class_name = NormalizeInvalidXmlChars ((asb != null ? asb.GetType () : typeof (ApplicationSettingsBase)).FullName);
622 ClientSettingsSection userSection = null;
623 ConfigurationSection cnf = userGroup.Sections.Get (class_name);
624 userSection = cnf as ClientSettingsSection;
625 if (userSection == null) {
626 userSection = new ClientSettingsSection ();
627 userGroup.Sections.Add (class_name, userSection);
630 bool hasChanges = false;
632 if (userSection == null)
635 foreach (SettingsPropertyValue value in collection) {
636 if (checkUserLevel && value.Property.Attributes.Contains (typeof (SettingsManageabilityAttribute)) != isRoaming)
638 // The default impl does not save the ApplicationScopedSetting properties
639 if (value.Property.Attributes.Contains (typeof (ApplicationScopedSettingAttribute)))
643 SettingElement element = userSection.Settings.Get (value.Name);
644 if (element == null) {
645 element = new SettingElement (value.Name, value.Property.SerializeAs);
646 userSection.Settings.Add (element);
648 if (element.Value.ValueXml == null)
649 element.Value.ValueXml = new XmlDocument ().CreateElement ("value");
650 switch (value.Property.SerializeAs) {
651 case SettingsSerializeAs.Xml:
652 element.Value.ValueXml.InnerXml = StripXmlHeader (value.SerializedValue as string);
654 case SettingsSerializeAs.String:
655 element.Value.ValueXml.InnerText = value.SerializedValue as string;
657 case SettingsSerializeAs.Binary:
658 element.Value.ValueXml.InnerText = value.SerializedValue != null ? Convert.ToBase64String (value.SerializedValue as byte []) : string.Empty;
661 throw new NotImplementedException ();
665 config.Save (ConfigurationSaveMode.Minimal, true);
668 // NOTE: We should add here all the chars that are valid in a name of a class (Ecma-wise),
669 // but invalid in an xml element name, and provide a better impl if we get too many of them.
670 string NormalizeInvalidXmlChars (string str)
672 char [] invalid_chars = new char [] { '+' };
674 if (str == null || str.IndexOfAny (invalid_chars) == -1)
677 // Replace with its hexadecimal values.
678 str = str.Replace ("+", "_x002B_");
682 private void LoadPropertyValue (SettingsPropertyCollection collection, SettingElement element, bool allowOverwrite)
684 SettingsProperty prop = collection [element.Name];
685 if (prop == null) { // see bug #343459
686 prop = new SettingsProperty (element.Name);
687 collection.Add (prop);
690 SettingsPropertyValue value = new SettingsPropertyValue (prop);
691 value.IsDirty = false;
692 if (element.Value.ValueXml != null) {
693 switch (value.Property.SerializeAs) {
694 case SettingsSerializeAs.Xml:
695 value.SerializedValue = element.Value.ValueXml.InnerXml;
697 case SettingsSerializeAs.String:
698 value.SerializedValue = element.Value.ValueXml.InnerText.Trim ();
700 case SettingsSerializeAs.Binary:
701 value.SerializedValue = Convert.FromBase64String (element.Value.ValueXml.InnerText);
706 value.SerializedValue = prop.DefaultValue;
710 values.Remove (element.Name);
712 } catch (ArgumentException ex) {
713 throw new ConfigurationErrorsException (string.Format (
714 CultureInfo.InvariantCulture,
715 "Failed to load value for '{0}'.",
720 private void LoadProperties (ExeConfigurationFileMap exeMap, SettingsPropertyCollection collection, ConfigurationUserLevel level, string sectionGroupName, bool allowOverwrite, string groupName)
722 Configuration config = ConfigurationManager.OpenMappedExeConfiguration (exeMap,level);
724 ConfigurationSectionGroup sectionGroup = config.GetSectionGroup (sectionGroupName);
725 if (sectionGroup != null) {
726 foreach (ConfigurationSection configSection in sectionGroup.Sections) {
727 if (configSection.SectionInformation.Name != groupName)
730 ClientSettingsSection clientSection = configSection as ClientSettingsSection;
731 if (clientSection == null)
734 foreach (SettingElement element in clientSection.Settings) {
735 LoadPropertyValue(collection, element, allowOverwrite);
737 // Only the first one seems to be processed by MS
744 public override void SetPropertyValues (SettingsContext context, SettingsPropertyValueCollection collection)
748 if (UserLocalFullPath == UserRoamingFullPath)
750 SaveProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoaming, context, false);
752 SaveProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoaming, context, true);
753 SaveProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoamingAndLocal, context, true);
757 public override SettingsPropertyValueCollection GetPropertyValues (SettingsContext context, SettingsPropertyCollection collection)
761 values = new SettingsPropertyValueCollection ();
762 string groupName = context ["GroupName"] as string;
763 groupName = NormalizeInvalidXmlChars (groupName); // we likely saved the element removing the non valid xml chars.
764 LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "applicationSettings", false, groupName);
765 LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.None, "userSettings", false, groupName);
767 LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoaming, "userSettings", true, groupName);
768 LoadProperties (exeMapCurrent, collection, ConfigurationUserLevel.PerUserRoamingAndLocal, "userSettings", true, groupName);
770 // create default values if not exist
771 foreach (SettingsProperty p in collection)
772 if (values [p.Name] == null)
773 values.Add (new SettingsPropertyValue (p));
777 /// creates an ExeConfigurationFileMap
778 private void CreateExeMap ()
780 if (exeMapCurrent == null) {
781 CreateUserConfigPath ();
784 exeMapCurrent = new ExeConfigurationFileMap ();
786 // exeMapCurrent.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
787 Assembly entry = Assembly.GetEntryAssembly () ?? Assembly.GetExecutingAssembly ();
788 exeMapCurrent.ExeConfigFilename = entry.Location + ".config";
789 exeMapCurrent.LocalUserConfigFilename = UserLocalFullPath;
790 exeMapCurrent.RoamingUserConfigFilename = UserRoamingFullPath;
792 if (webConfigurationFileMapType != null && typeof (ConfigurationFileMap).IsAssignableFrom (webConfigurationFileMapType)) {
794 ConfigurationFileMap cfgFileMap = Activator.CreateInstance (webConfigurationFileMapType) as ConfigurationFileMap;
795 if (cfgFileMap != null) {
796 string fpath = cfgFileMap.MachineConfigFilename;
797 if (!String.IsNullOrEmpty (fpath))
798 exeMapCurrent.ExeConfigFilename = fpath;
806 if ((PrevUserLocalFullPath != "") && (PrevUserRoamingFullPath != ""))
808 exeMapPrev = new ExeConfigurationFileMap();
809 // exeMapPrev.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
810 exeMapPrev.ExeConfigFilename = entry.Location + ".config";
811 exeMapPrev.LocalUserConfigFilename = PrevUserLocalFullPath;
812 exeMapPrev.RoamingUserConfigFilename = PrevUserRoamingFullPath;
818 public SettingsPropertyValue GetPreviousVersion (SettingsContext context, SettingsProperty property)
823 public void Reset (SettingsContext context)
825 if (values != null) {
826 foreach (SettingsPropertyValue propertyValue in values) {
827 // Can't use propertyValue.Property.DefaultValue
828 // as it may cause InvalidCastException (see bug# 532180)
829 values[propertyValue.Name].PropertyValue = propertyValue.Reset ();
835 public void Upgrade (SettingsContext context, SettingsPropertyCollection properties)
839 public static void setCreate ()
841 CreateUserConfigPath();