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.
33 using System
.Collections
;
34 using System
.Collections
.Generic
;
35 using System
.Collections
.Specialized
;
36 using System
.Configuration
;
37 using System
.Globalization
;
39 using System
.Reflection
;
40 using System
.Security
.Cryptography
;
44 namespace System
.Configuration
46 // location to store user configuration settings.
47 internal enum UserConfigLocationOption
: uint
50 Product_VersionMajor
= 0x21,
51 Product_VersionMinor
= 0x22,
52 Product_VersionBuild
= 0x24,
53 Product_VersionRevision
= 0x28,
54 Company_Product
= 0x30,
55 Company_Product_VersionMajor
= 0x31,
56 Company_Product_VersionMinor
= 0x32,
57 Company_Product_VersionBuild
= 0x34,
58 Company_Product_VersionRevision
= 0x38,
63 internal class CustomizableFileSettingsProvider
: SettingsProvider
, IApplicationSettingsProvider
67 // This is used from within System.Web to allow mapping of the ExeConfigFilename to
68 // the correct Web.config for the current request. Otherwise web applications will
69 // not be able to access settings from Web.config. The type assigned to this
70 // variable must descend from the ConfigurationFileMap class and its
71 // MachineConfigFilename will be used to set the ExeConfigFilename.
73 // This is necessary to fix bug #491531
74 #pragma warning disable 649
75 private static Type webConfigurationFileMapType
;
76 #pragma warning restore 649
78 private static string userRoamingPath
= "";
79 private static string userLocalPath
= "";
80 private static string userRoamingPathPrevVersion
= "";
81 private static string userLocalPathPrevVersion
= "";
82 private static string userRoamingName
= "user.config";
83 private static string userLocalName
= "user.config";
84 private static string userRoamingBasePath
= "";
85 private static string userLocalBasePath
= "";
86 private static string CompanyName
= "";
87 private static string ProductName
= "";
88 private static string ForceVersion
= "";
89 private static string[] ProductVersion
;
91 // whether to include parts in the folder name or not:
92 private static bool isVersionMajor
= false; // 0x0001 major version
93 private static bool isVersionMinor
= false; // 0x0002 minor version
94 private static bool isVersionBuild
= false; // 0x0004 build version
95 private static bool isVersionRevision
= false; // 0x0008 revision
96 private static bool isCompany
= true; // 0x0010 corporate name
97 private static bool isProduct
= true; // 0x0020 product name
98 private static bool isEvidence
= false; // 0x0040 evidence hash
100 private static bool userDefine
= false; // 0x8000 ignore all above and use user definition
102 private static UserConfigLocationOption userConfig
= UserConfigLocationOption
.Company_Product
;
104 public override void Initialize (string name
, NameValueCollection config
)
106 base.Initialize (name
, config
);
109 // full path to roaming user.config
110 internal static string UserRoamingFullPath
{
111 get { return Path.Combine (userRoamingPath, userRoamingName); }
114 // full path to local user.config
115 internal static string UserLocalFullPath
{
116 get { return Path.Combine (userLocalPath, userLocalName); }
119 // previous full path to roaming user.config
120 public static string PrevUserRoamingFullPath
{
121 get { return Path.Combine (userRoamingPathPrevVersion, userRoamingName); }
124 // previous full path to local user.config
125 public static string PrevUserLocalFullPath
{
126 get { return Path.Combine (userLocalPathPrevVersion, userLocalName); }
129 // path to roaming user.config
130 public static string UserRoamingPath
{
131 get { return userRoamingPath; }
134 // path to local user.config
135 public static string UserLocalPath
{
136 get { return userLocalPath; }
139 // file name which is equivalent to user.config, for roaming user
140 public static string UserRoamingName
{
141 get { return userRoamingName; }
144 // file name which is equivalent to user.config, for local user
145 public static string UserLocalName
{
146 get { return userLocalName; }
149 public static UserConfigLocationOption UserConfigSelector
151 get { return userConfig; }
155 if (((uint) userConfig
& 0x8000) != 0) {
156 isVersionMajor
= false;
157 isVersionMinor
= false;
158 isVersionBuild
= false;
159 isVersionRevision
= false;
164 isVersionRevision
= ((uint) userConfig
& 0x0008) != 0;
165 isVersionBuild
= isVersionRevision
| ((uint)userConfig
& 0x0004) != 0;
166 isVersionMinor
= isVersionBuild
| ((uint)userConfig
& 0x0002) != 0;
167 isVersionMajor
= IsVersionMinor
| ((uint)userConfig
& 0x0001) != 0;
169 isCompany
= ((uint) userConfig
& 0x0010) != 0;
170 isProduct
= ((uint) userConfig
& 0x0020) != 0;
174 // whether the path to include the major version.
175 public static bool IsVersionMajor
177 get { return isVersionMajor; }
180 isVersionMajor
= value;
181 isVersionMinor
= false;
182 isVersionBuild
= false;
183 isVersionRevision
= false;
187 // whether the path to include minor version.
188 public static bool IsVersionMinor
190 get { return isVersionMinor; }
193 isVersionMinor
= value;
195 isVersionMajor
= true;
196 isVersionBuild
= false;
197 isVersionRevision
= false;
201 // whether the path to include build version.
202 public static bool IsVersionBuild
204 get { return isVersionBuild; }
207 isVersionBuild
= value;
208 if (isVersionBuild
) {
209 isVersionMajor
= true;
210 isVersionMinor
= true;
212 isVersionRevision
= false;
216 // whether the path to include revision.
217 public static bool IsVersionRevision
219 get { return isVersionRevision; }
222 isVersionRevision
= value;
223 if (isVersionRevision
) {
224 isVersionMajor
= true;
225 isVersionMinor
= true;
226 isVersionBuild
= true;
231 // whether the path to include company name.
232 public static bool IsCompany
234 get { return isCompany; }
235 set { isCompany = value; }
238 // whether the path to include evidence hash.
239 public static bool IsEvidence
241 get { return isEvidence; }
242 set { isEvidence = value; }
245 // AssemblyCompanyAttribute->Namespace->"Program"
246 private static string GetCompanyName ()
248 Assembly assembly
= Assembly
.GetEntryAssembly ();
249 if (assembly
== null)
250 assembly
= Assembly
.GetCallingAssembly ();
252 AssemblyCompanyAttribute
[] attrs
= (AssemblyCompanyAttribute
[]) assembly
.GetCustomAttributes (typeof (AssemblyCompanyAttribute
), true);
254 if ((attrs
!= null) && attrs
.Length
> 0) {
255 return attrs
[0].Company
;
258 MethodInfo entryPoint
= assembly
.EntryPoint
;
259 Type entryType
= entryPoint
!= null ? entryPoint
.DeclaringType
: null;
260 if (entryType
!= null && !String
.IsNullOrEmpty (entryType
.Namespace
)) {
261 int end
= entryType
.Namespace
.IndexOf ('.');
262 return end
< 0 ? entryType
.Namespace
: entryType
.Namespace
.Substring (0, end
);
267 private static string GetProductName ()
269 Assembly assembly
= Assembly
.GetEntryAssembly ();
270 if (assembly
== null)
271 assembly
= Assembly
.GetCallingAssembly ();
273 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
274 return String
.Format ("{0}_{1}_{2}",
275 AppDomain
.CurrentDomain
.FriendlyName
,
276 pkt
!= null && pkt
.Length
> 0 ? "StrongName" : "Url",
280 // Note: Changed from base64() to hex output to avoid unexpected chars like '\' or '/' with filesystem meaning.
281 // Otherwise eventually filenames, which are invalid on linux or windows, might be created.
282 // Signed-off-by: Carsten Schlote <schlote@vahanus.net>
283 // TODO: Compare with .NET. It might be also, that their way isn't suitable for Unix OS derivates (slahes in output)
284 private static string GetEvidenceHash ()
286 Assembly assembly
= Assembly
.GetEntryAssembly ();
287 if (assembly
== null)
288 assembly
= Assembly
.GetCallingAssembly ();
290 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
291 byte [] hash
= SHA1
.Create ().ComputeHash (pkt
!= null && pkt
.Length
>0 ? pkt
: Encoding
.UTF8
.GetBytes (assembly
.EscapedCodeBase
));
292 System
.Text
.StringBuilder evidence_string
= new System
.Text
.StringBuilder();
293 foreach (byte b
in hash
)
294 evidence_string
.AppendFormat("{0:x2}",b
);
295 return evidence_string
.ToString ();
298 private static string GetProductVersion ()
300 Assembly assembly
= Assembly
.GetEntryAssembly ();
301 if (assembly
== null)
302 assembly
= Assembly
.GetCallingAssembly ();
303 if (assembly
== null)
306 return assembly
.GetName ().Version
.ToString ();
309 private static void CreateUserConfigPath ()
314 if (ProductName
== "")
315 ProductName
= GetProductName ();
316 if (CompanyName
== "")
317 CompanyName
= GetCompanyName ();
318 if (ForceVersion
== "")
319 ProductVersion
= GetProductVersion ().Split('.');
321 // C:\Documents and Settings\(user)\Application Data
322 if (userRoamingBasePath
== "")
323 userRoamingPath
= Environment
.GetFolderPath (Environment
.SpecialFolder
.ApplicationData
);
325 userRoamingPath
= userRoamingBasePath
;
327 // C:\Documents and Settings\(user)\Local Settings\Application Data (on Windows)
328 if (userLocalBasePath
== "")
329 userLocalPath
= Environment
.GetFolderPath (Environment
.SpecialFolder
.LocalApplicationData
);
331 userLocalPath
= userLocalBasePath
;
334 userRoamingPath
= Path
.Combine (userRoamingPath
, CompanyName
);
335 userLocalPath
= Path
.Combine (userLocalPath
, CompanyName
);
340 Assembly assembly
= Assembly
.GetEntryAssembly ();
341 if (assembly
== null)
342 assembly
= Assembly
.GetCallingAssembly ();
343 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
344 ProductName
= String
.Format ("{0}_{1}_{2}",
346 pkt
!= null ? "StrongName" : "Url",
349 userRoamingPath
= Path
.Combine (userRoamingPath
, ProductName
);
350 userLocalPath
= Path
.Combine (userLocalPath
, ProductName
);
356 if (ForceVersion
== "") {
357 if (isVersionRevision
)
358 versionName
= String
.Format ("{0}.{1}.{2}.{3}", ProductVersion
[0], ProductVersion
[1], ProductVersion
[2], ProductVersion
[3]);
359 else if (isVersionBuild
)
360 versionName
= String
.Format ("{0}.{1}.{2}", ProductVersion
[0], ProductVersion
[1], ProductVersion
[2]);
361 else if (isVersionMinor
)
362 versionName
= String
.Format ("{0}.{1}", ProductVersion
[0], ProductVersion
[1]);
363 else if (isVersionMajor
)
364 versionName
= ProductVersion
[0];
369 versionName
= ForceVersion
;
371 string prevVersionRoaming
= PrevVersionPath (userRoamingPath
, versionName
);
372 string prevVersionLocal
= PrevVersionPath (userLocalPath
, versionName
);
374 userRoamingPath
= Path
.Combine (userRoamingPath
, versionName
);
375 userLocalPath
= Path
.Combine (userLocalPath
, versionName
);
376 if (prevVersionRoaming
!= "")
377 userRoamingPathPrevVersion
= Path
.Combine(userRoamingPath
, prevVersionRoaming
);
378 if (prevVersionLocal
!= "")
379 userLocalPathPrevVersion
= Path
.Combine(userLocalPath
, prevVersionLocal
);
382 // string for the previous version. It ignores newer ones.
383 private static string PrevVersionPath (string dirName
, string currentVersion
)
385 string prevVersionString
= "";
387 if (!Directory
.Exists(dirName
))
388 return prevVersionString
;
389 DirectoryInfo currentDir
= new DirectoryInfo (dirName
);
390 foreach (DirectoryInfo dirInfo
in currentDir
.GetDirectories ())
391 if (String
.Compare (currentVersion
, dirInfo
.Name
, StringComparison
.Ordinal
) > 0)
392 if (String
.Compare (prevVersionString
, dirInfo
.Name
, StringComparison
.Ordinal
) < 0)
393 prevVersionString
= dirInfo
.Name
;
395 return prevVersionString
;
398 // sets the explicit path to store roaming user.config or equivalent.
399 // (returns the path validity.)
400 public static bool SetUserRoamingPath (string configPath
)
402 if (CheckPath (configPath
))
404 userRoamingBasePath
= configPath
;
411 // sets the explicit path to store local user.config or equivalent.
412 // (returns the path validity.)
413 public static bool SetUserLocalPath (string configPath
)
415 if (CheckPath (configPath
))
417 userLocalBasePath
= configPath
;
424 private static bool CheckFileName (string configFile
)
427 char[] invalidFileChars = Path.GetInvalidFileNameChars();
429 foreach (char invalidChar in invalidFileChars)
431 if (configFile.Contains(invalidChar.ToString()))
438 return configFile
.IndexOfAny (Path
.GetInvalidFileNameChars ()) < 0;
441 // sets the explicit roaming file name which is user.config equivalent.
442 // (returns the file name validity.)
443 public static bool SetUserRoamingFileName (string configFile
)
445 if (CheckFileName (configFile
))
447 userRoamingName
= configFile
;
454 // sets the explicit local file name which is user.config equivalent.
455 // (returns the file name validity.)
456 public static bool SetUserLocalFileName (string configFile
)
458 if (CheckFileName (configFile
))
460 userLocalName
= configFile
;
467 // sets the explicit company name for folder.
468 // (returns the file name validity.)
469 public static bool SetCompanyName (string companyName
)
471 if (CheckFileName (companyName
))
473 CompanyName
= companyName
;
480 // sets the explicit product name for folder.
481 // (returns the file name validity.)
482 public static bool SetProductName (string productName
)
484 if (CheckFileName (productName
))
486 ProductName
= productName
;
493 // sets the explicit major version for folder.
494 public static bool SetVersion (int major
)
496 ForceVersion
= string.Format ("{0}", major
);
500 // sets the explicit major and minor versions for folder.
501 public static bool SetVersion (int major
, int minor
)
503 ForceVersion
= string.Format ("{0}.{1}", major
, minor
);
507 // sets the explicit major/minor/build numbers for folder.
508 public static bool SetVersion (int major
, int minor
, int build
)
510 ForceVersion
= string.Format ("{0}.{1}.{2}", major
, minor
, build
);
514 // sets the explicit major/minor/build/revision numbers for folder.
515 public static bool SetVersion (int major
, int minor
, int build
, int revision
)
517 ForceVersion
= string.Format ("{0}.{1}.{2}.{3}", major
, minor
, build
, revision
);
521 // sets the explicit version number string for folder.
522 public static bool SetVersion (string forceVersion
)
524 if (CheckFileName (forceVersion
))
526 ForceVersion
= forceVersion
;
533 private static bool CheckPath (string configPath
)
535 char[] invalidPathChars
= Path
.GetInvalidPathChars ();
538 foreach (char invalidChar in invalidPathChars)
540 if (configPath.Contains (invalidChar.ToString()))
546 if (configPath
.IndexOfAny (invalidPathChars
) >= 0)
549 string folder
= configPath
;
551 while ((fileName
= Path
.GetFileName (folder
)) != "")
553 if (!CheckFileName (fileName
))
557 folder
= Path
.GetDirectoryName (folder
);
564 public override string Name
{
565 get { return base.Name; }
568 string app_name
= String
.Empty
;//"OJK.CustomSetting.CustomizableLocalFileSettingsProvider";
569 public override string ApplicationName
{
570 get { return app_name; }
571 set { app_name = value; }
574 private ExeConfigurationFileMap exeMapCurrent
= null;
575 private ExeConfigurationFileMap exeMapPrev
= null;
576 private SettingsPropertyValueCollection values
= null;
579 /// Hack to remove the XmlDeclaration that the XmlSerializer adds.
581 /// see <a href="https://github.com/mono/mono/pull/2273">Issue 2273</a> for details
583 private string StripXmlHeader (string serializedValue
)
585 if (serializedValue
== null)
590 XmlDocument doc
= new XmlDocument ();
591 XmlElement valueXml
= doc
.CreateElement ("value");
592 valueXml
.InnerXml
= serializedValue
;
594 foreach (XmlNode child
in valueXml
.ChildNodes
) {
595 if (child
.NodeType
== XmlNodeType
.XmlDeclaration
) {
596 valueXml
.RemoveChild (child
);
601 // InnerXml will give you well-formed XML that you could save as a separate document, and
602 // InnerText will immediately give you a pure-text representation of this inner XML.
603 return valueXml
.InnerXml
;
606 private void SaveProperties (ExeConfigurationFileMap exeMap
, SettingsPropertyValueCollection collection
, ConfigurationUserLevel level
, SettingsContext context
, bool checkUserLevel
)
608 Configuration config
= ConfigurationManager
.OpenMappedExeConfiguration (exeMap
, level
);
610 UserSettingsGroup userGroup
= config
.GetSectionGroup ("userSettings") as UserSettingsGroup
;
611 bool isRoaming
= (level
== ConfigurationUserLevel
.PerUserRoaming
);
613 if (userGroup
== null) {
614 userGroup
= new UserSettingsGroup ();
615 config
.SectionGroups
.Add ("userSettings", userGroup
);
617 ApplicationSettingsBase asb
= context
.CurrentSettings
;
618 string class_name
= NormalizeInvalidXmlChars ((asb
!= null ? asb
.GetType () : typeof (ApplicationSettingsBase
)).FullName
);
619 ClientSettingsSection userSection
= null;
620 ConfigurationSection cnf
= userGroup
.Sections
.Get (class_name
);
621 userSection
= cnf
as ClientSettingsSection
;
622 if (userSection
== null) {
623 userSection
= new ClientSettingsSection ();
624 userGroup
.Sections
.Add (class_name
, userSection
);
627 bool hasChanges
= false;
629 if (userSection
== null)
632 foreach (SettingsPropertyValue
value in collection
) {
633 if (checkUserLevel
&& value.Property
.Attributes
.Contains (typeof (SettingsManageabilityAttribute
)) != isRoaming
)
635 // The default impl does not save the ApplicationScopedSetting properties
636 if (value.Property
.Attributes
.Contains (typeof (ApplicationScopedSettingAttribute
)))
640 SettingElement element
= userSection
.Settings
.Get (value.Name
);
641 if (element
== null) {
642 element
= new SettingElement (value.Name
, value.Property
.SerializeAs
);
643 userSection
.Settings
.Add (element
);
645 if (element
.Value
.ValueXml
== null)
646 element
.Value
.ValueXml
= new XmlDocument ().CreateElement ("value");
647 switch (value.Property
.SerializeAs
) {
648 case SettingsSerializeAs
.Xml
:
649 element
.Value
.ValueXml
.InnerXml
= StripXmlHeader (value.SerializedValue
as string);
651 case SettingsSerializeAs
.String
:
652 element
.Value
.ValueXml
.InnerText
= value.SerializedValue
as string;
654 case SettingsSerializeAs
.Binary
:
655 element
.Value
.ValueXml
.InnerText
= value.SerializedValue
!= null ? Convert
.ToBase64String (value.SerializedValue
as byte []) : string.Empty
;
658 throw new NotImplementedException ();
662 config
.Save (ConfigurationSaveMode
.Minimal
, true);
665 // NOTE: We should add here all the chars that are valid in a name of a class (Ecma-wise),
666 // but invalid in an xml element name, and provide a better impl if we get too many of them.
667 string NormalizeInvalidXmlChars (string str
)
669 char [] invalid_chars
= new char [] { '+' }
;
671 if (str
== null || str
.IndexOfAny (invalid_chars
) == -1)
674 // Replace with its hexadecimal values.
675 str
= str
.Replace ("+", "_x002B_");
679 private void LoadPropertyValue (SettingsPropertyCollection collection
, SettingElement element
, bool allowOverwrite
)
681 SettingsProperty prop
= collection
[element
.Name
];
682 if (prop
== null) { // see bug #343459
683 prop
= new SettingsProperty (element
.Name
);
684 collection
.Add (prop
);
687 SettingsPropertyValue
value = new SettingsPropertyValue (prop
);
688 value.IsDirty
= false;
689 if (element
.Value
.ValueXml
!= null) {
690 switch (value.Property
.SerializeAs
) {
691 case SettingsSerializeAs
.Xml
:
692 value.SerializedValue
= element
.Value
.ValueXml
.InnerXml
;
694 case SettingsSerializeAs
.String
:
695 value.SerializedValue
= element
.Value
.ValueXml
.InnerText
.Trim ();
697 case SettingsSerializeAs
.Binary
:
698 value.SerializedValue
= Convert
.FromBase64String (element
.Value
.ValueXml
.InnerText
);
703 value.SerializedValue
= prop
.DefaultValue
;
707 values
.Remove (element
.Name
);
709 } catch (ArgumentException ex
) {
710 throw new ConfigurationErrorsException (string.Format (
711 CultureInfo
.InvariantCulture
,
712 "Failed to load value for '{0}'.",
717 private void LoadProperties (ExeConfigurationFileMap exeMap
, SettingsPropertyCollection collection
, ConfigurationUserLevel level
, string sectionGroupName
, bool allowOverwrite
, string groupName
)
719 Configuration config
= ConfigurationManager
.OpenMappedExeConfiguration (exeMap
,level
);
721 ConfigurationSectionGroup sectionGroup
= config
.GetSectionGroup (sectionGroupName
);
722 if (sectionGroup
!= null) {
723 foreach (ConfigurationSection configSection
in sectionGroup
.Sections
) {
724 if (configSection
.SectionInformation
.Name
!= groupName
)
727 ClientSettingsSection clientSection
= configSection
as ClientSettingsSection
;
728 if (clientSection
== null)
731 foreach (SettingElement element
in clientSection
.Settings
) {
732 LoadPropertyValue(collection
, element
, allowOverwrite
);
734 // Only the first one seems to be processed by MS
741 public override void SetPropertyValues (SettingsContext context
, SettingsPropertyValueCollection collection
)
745 if (UserLocalFullPath
== UserRoamingFullPath
)
747 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, context
, false);
749 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, context
, true);
750 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoamingAndLocal
, context
, true);
754 public override SettingsPropertyValueCollection
GetPropertyValues (SettingsContext context
, SettingsPropertyCollection collection
)
758 values
= new SettingsPropertyValueCollection ();
759 string groupName
= context
["GroupName"] as string;
760 groupName
= NormalizeInvalidXmlChars (groupName
); // we likely saved the element removing the non valid xml chars.
761 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.None
, "applicationSettings", false, groupName
);
762 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.None
, "userSettings", false, groupName
);
764 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, "userSettings", true, groupName
);
765 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoamingAndLocal
, "userSettings", true, groupName
);
767 // create default values if not exist
768 foreach (SettingsProperty p
in collection
)
769 if (values
[p
.Name
] == null)
770 values
.Add (new SettingsPropertyValue (p
));
774 /// creates an ExeConfigurationFileMap
775 private void CreateExeMap ()
777 if (exeMapCurrent
== null) {
778 CreateUserConfigPath ();
781 exeMapCurrent
= new ExeConfigurationFileMap ();
783 // exeMapCurrent.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
784 Assembly entry
= Assembly
.GetEntryAssembly () ?? Assembly
.GetExecutingAssembly ();
785 exeMapCurrent
.ExeConfigFilename
= entry
.Location
+ ".config";
786 exeMapCurrent
.LocalUserConfigFilename
= UserLocalFullPath
;
787 exeMapCurrent
.RoamingUserConfigFilename
= UserRoamingFullPath
;
789 if (webConfigurationFileMapType
!= null && typeof (ConfigurationFileMap
).IsAssignableFrom (webConfigurationFileMapType
)) {
791 ConfigurationFileMap cfgFileMap
= Activator
.CreateInstance (webConfigurationFileMapType
) as ConfigurationFileMap
;
792 if (cfgFileMap
!= null) {
793 string fpath
= cfgFileMap
.MachineConfigFilename
;
794 if (!String
.IsNullOrEmpty (fpath
))
795 exeMapCurrent
.ExeConfigFilename
= fpath
;
803 if ((PrevUserLocalFullPath
!= "") && (PrevUserRoamingFullPath
!= ""))
805 exeMapPrev
= new ExeConfigurationFileMap();
806 // exeMapPrev.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
807 exeMapPrev
.ExeConfigFilename
= entry
.Location
+ ".config";
808 exeMapPrev
.LocalUserConfigFilename
= PrevUserLocalFullPath
;
809 exeMapPrev
.RoamingUserConfigFilename
= PrevUserRoamingFullPath
;
815 public SettingsPropertyValue
GetPreviousVersion (SettingsContext context
, SettingsProperty property
)
820 public void Reset (SettingsContext context
)
822 if (values
!= null) {
823 foreach (SettingsPropertyValue propertyValue
in values
) {
824 // Can't use propertyValue.Property.DefaultValue
825 // as it may cause InvalidCastException (see bug# 532180)
826 values
[propertyValue
.Name
].PropertyValue
= propertyValue
.Reset ();
832 public void Upgrade (SettingsContext context
, SettingsPropertyCollection properties
)
836 public static void setCreate ()
838 CreateUserConfigPath();