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 extern alias PrebuiltSystem
;
37 using System
.Collections
;
38 using System
.Collections
.Generic
;
39 using System
.Configuration
;
40 using System
.Globalization
;
42 using System
.Reflection
;
43 using System
.Security
.Cryptography
;
48 using NameValueCollection
= System
.Collections
.Specialized
.NameValueCollection
;
50 using NameValueCollection
= PrebuiltSystem
.System
.Collections
.Specialized
.NameValueCollection
;
53 namespace System
.Configuration
55 // location to store user configuration settings.
56 internal enum UserConfigLocationOption
: uint
59 Product_VersionMajor
= 0x21,
60 Product_VersionMinor
= 0x22,
61 Product_VersionBuild
= 0x24,
62 Product_VersionRevision
= 0x28,
63 Company_Product
= 0x30,
64 Company_Product_VersionMajor
= 0x31,
65 Company_Product_VersionMinor
= 0x32,
66 Company_Product_VersionBuild
= 0x34,
67 Company_Product_VersionRevision
= 0x38,
72 internal class CustomizableFileSettingsProvider
: SettingsProvider
, IApplicationSettingsProvider
76 // This is used from within System.Web to allow mapping of the ExeConfigFilename to
77 // the correct Web.config for the current request. Otherwise web applications will
78 // not be able to access settings from Web.config. The type assigned to this
79 // variable must descend from the ConfigurationFileMap class and its
80 // MachineConfigFilename will be used to set the ExeConfigFilename.
82 // This is necessary to fix bug #491531
83 #pragma warning disable 649
84 private static Type webConfigurationFileMapType
;
85 #pragma warning restore 649
87 private static string userRoamingPath
= "";
88 private static string userLocalPath
= "";
89 private static string userRoamingPathPrevVersion
= "";
90 private static string userLocalPathPrevVersion
= "";
91 private static string userRoamingName
= "user.config";
92 private static string userLocalName
= "user.config";
93 private static string userRoamingBasePath
= "";
94 private static string userLocalBasePath
= "";
95 private static string CompanyName
= "";
96 private static string ProductName
= "";
97 private static string ForceVersion
= "";
98 private static string[] ProductVersion
;
100 // whether to include parts in the folder name or not:
101 private static bool isVersionMajor
= false; // 0x0001 major version
102 private static bool isVersionMinor
= false; // 0x0002 minor version
103 private static bool isVersionBuild
= false; // 0x0004 build version
104 private static bool isVersionRevision
= false; // 0x0008 revision
105 private static bool isCompany
= true; // 0x0010 corporate name
106 private static bool isProduct
= true; // 0x0020 product name
107 private static bool isEvidence
= false; // 0x0040 evidence hash
109 private static bool userDefine
= false; // 0x8000 ignore all above and use user definition
111 private static UserConfigLocationOption userConfig
= UserConfigLocationOption
.Company_Product
;
113 public override void Initialize (string name
, NameValueCollection config
)
115 base.Initialize (name
, config
);
118 // full path to roaming user.config
119 internal static string UserRoamingFullPath
{
120 get { return Path.Combine (userRoamingPath, userRoamingName); }
123 // full path to local user.config
124 internal static string UserLocalFullPath
{
125 get { return Path.Combine (userLocalPath, userLocalName); }
128 // previous full path to roaming user.config
129 public static string PrevUserRoamingFullPath
{
130 get { return Path.Combine (userRoamingPathPrevVersion, userRoamingName); }
133 // previous full path to local user.config
134 public static string PrevUserLocalFullPath
{
135 get { return Path.Combine (userLocalPathPrevVersion, userLocalName); }
138 // path to roaming user.config
139 public static string UserRoamingPath
{
140 get { return userRoamingPath; }
143 // path to local user.config
144 public static string UserLocalPath
{
145 get { return userLocalPath; }
148 // file name which is equivalent to user.config, for roaming user
149 public static string UserRoamingName
{
150 get { return userRoamingName; }
153 // file name which is equivalent to user.config, for local user
154 public static string UserLocalName
{
155 get { return userLocalName; }
158 public static UserConfigLocationOption UserConfigSelector
160 get { return userConfig; }
164 if (((uint) userConfig
& 0x8000) != 0) {
165 isVersionMajor
= false;
166 isVersionMinor
= false;
167 isVersionBuild
= false;
168 isVersionRevision
= false;
173 isVersionRevision
= ((uint) userConfig
& 0x0008) != 0;
174 isVersionBuild
= isVersionRevision
| ((uint)userConfig
& 0x0004) != 0;
175 isVersionMinor
= isVersionBuild
| ((uint)userConfig
& 0x0002) != 0;
176 isVersionMajor
= IsVersionMinor
| ((uint)userConfig
& 0x0001) != 0;
178 isCompany
= ((uint) userConfig
& 0x0010) != 0;
179 isProduct
= ((uint) userConfig
& 0x0020) != 0;
183 // whether the path to include the major version.
184 public static bool IsVersionMajor
186 get { return isVersionMajor; }
189 isVersionMajor
= value;
190 isVersionMinor
= false;
191 isVersionBuild
= false;
192 isVersionRevision
= false;
196 // whether the path to include minor version.
197 public static bool IsVersionMinor
199 get { return isVersionMinor; }
202 isVersionMinor
= value;
204 isVersionMajor
= true;
205 isVersionBuild
= false;
206 isVersionRevision
= false;
210 // whether the path to include build version.
211 public static bool IsVersionBuild
213 get { return isVersionBuild; }
216 isVersionBuild
= value;
217 if (isVersionBuild
) {
218 isVersionMajor
= true;
219 isVersionMinor
= true;
221 isVersionRevision
= false;
225 // whether the path to include revision.
226 public static bool IsVersionRevision
228 get { return isVersionRevision; }
231 isVersionRevision
= value;
232 if (isVersionRevision
) {
233 isVersionMajor
= true;
234 isVersionMinor
= true;
235 isVersionBuild
= true;
240 // whether the path to include company name.
241 public static bool IsCompany
243 get { return isCompany; }
244 set { isCompany = value; }
247 // whether the path to include evidence hash.
248 public static bool IsEvidence
250 get { return isEvidence; }
251 set { isEvidence = value; }
254 // AssemblyCompanyAttribute->Namespace->"Program"
255 private static string GetCompanyName ()
257 Assembly assembly
= Assembly
.GetEntryAssembly ();
258 if (assembly
== null)
259 assembly
= Assembly
.GetCallingAssembly ();
261 AssemblyCompanyAttribute
[] attrs
= (AssemblyCompanyAttribute
[]) assembly
.GetCustomAttributes (typeof (AssemblyCompanyAttribute
), true);
263 if ((attrs
!= null) && attrs
.Length
> 0) {
264 return attrs
[0].Company
;
268 MethodInfo entryPoint
= assembly
.EntryPoint
;
269 Type entryType
= entryPoint
!= null ? entryPoint
.DeclaringType
: null;
270 if (entryType
!= null && !String
.IsNullOrEmpty (entryType
.Namespace
)) {
271 int end
= entryType
.Namespace
.IndexOf ('.');
272 return end
< 0 ? entryType
.Namespace
: entryType
.Namespace
.Substring (0, end
);
276 return assembly
.GetName ().Name
;
280 private static string GetProductName ()
282 Assembly assembly
= Assembly
.GetEntryAssembly ();
283 if (assembly
== null)
284 assembly
= Assembly
.GetCallingAssembly ();
287 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
288 return String
.Format ("{0}_{1}_{2}",
289 AppDomain
.CurrentDomain
.FriendlyName
,
290 pkt
!= null && pkt
.Length
> 0 ? "StrongName" : "Url",
292 #else // AssemblyProductAttribute-based code
293 AssemblyProductAttribute
[] attrs
= (AssemblyProductAttribute
[]) assembly
.GetCustomAttributes (typeof (AssemblyProductAttribute
), true);
295 if ((attrs
!= null) && attrs
.Length
> 0) {
296 return attrs
[0].Product
;
298 return assembly
.GetName ().Name
;
302 // Note: Changed from base64() to hex output to avoid unexpected chars like '\' or '/' with filesystem meaning.
303 // Otherwise eventually filenames, which are invalid on linux or windows, might be created.
304 // Signed-off-by: Carsten Schlote <schlote@vahanus.net>
305 // TODO: Compare with .NET. It might be also, that their way isn't suitable for Unix OS derivates (slahes in output)
306 private static string GetEvidenceHash ()
308 Assembly assembly
= Assembly
.GetEntryAssembly ();
309 if (assembly
== null)
310 assembly
= Assembly
.GetCallingAssembly ();
312 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
313 byte [] hash
= SHA1
.Create ().ComputeHash (pkt
!= null && pkt
.Length
>0 ? pkt
: Encoding
.UTF8
.GetBytes (assembly
.EscapedCodeBase
));
314 System
.Text
.StringBuilder evidence_string
= new System
.Text
.StringBuilder();
315 foreach (byte b
in hash
)
316 evidence_string
.AppendFormat("{0:x2}",b
);
317 return evidence_string
.ToString ();
320 private static string GetProductVersion ()
322 Assembly assembly
= Assembly
.GetEntryAssembly ();
323 if (assembly
== null)
324 assembly
= Assembly
.GetCallingAssembly ();
325 if (assembly
== null)
328 return assembly
.GetName ().Version
.ToString ();
331 private static void CreateUserConfigPath ()
336 if (ProductName
== "")
337 ProductName
= GetProductName ();
338 if (CompanyName
== "")
339 CompanyName
= GetCompanyName ();
340 if (ForceVersion
== "")
341 ProductVersion
= GetProductVersion ().Split('.');
343 // C:\Documents and Settings\(user)\Application Data
345 if (userRoamingBasePath
== "")
346 userRoamingPath
= Environment
.GetFolderPath (Environment
.SpecialFolder
.ApplicationData
);
349 userRoamingPath
= userRoamingBasePath
;
351 // C:\Documents and Settings\(user)\Local Settings\Application Data (on Windows)
353 if (userLocalBasePath
== "")
354 userLocalPath
= Environment
.GetFolderPath (Environment
.SpecialFolder
.LocalApplicationData
);
357 userLocalPath
= userLocalBasePath
;
360 userRoamingPath
= Path
.Combine (userRoamingPath
, CompanyName
);
361 userLocalPath
= Path
.Combine (userLocalPath
, CompanyName
);
366 Assembly assembly
= Assembly
.GetEntryAssembly ();
367 if (assembly
== null)
368 assembly
= Assembly
.GetCallingAssembly ();
370 byte [] pkt
= assembly
.GetName ().GetPublicKeyToken ();
371 ProductName
= String
.Format ("{0}_{1}_{2}",
373 pkt
!= null ? "StrongName" : "Url",
377 userRoamingPath
= Path
.Combine (userRoamingPath
, ProductName
);
378 userLocalPath
= Path
.Combine (userLocalPath
, ProductName
);
384 if (ForceVersion
== "") {
385 if (isVersionRevision
)
386 versionName
= String
.Format ("{0}.{1}.{2}.{3}", ProductVersion
[0], ProductVersion
[1], ProductVersion
[2], ProductVersion
[3]);
387 else if (isVersionBuild
)
388 versionName
= String
.Format ("{0}.{1}.{2}", ProductVersion
[0], ProductVersion
[1], ProductVersion
[2]);
389 else if (isVersionMinor
)
390 versionName
= String
.Format ("{0}.{1}", ProductVersion
[0], ProductVersion
[1]);
391 else if (isVersionMajor
)
392 versionName
= ProductVersion
[0];
397 versionName
= ForceVersion
;
399 string prevVersionRoaming
= PrevVersionPath (userRoamingPath
, versionName
);
400 string prevVersionLocal
= PrevVersionPath (userLocalPath
, versionName
);
402 userRoamingPath
= Path
.Combine (userRoamingPath
, versionName
);
403 userLocalPath
= Path
.Combine (userLocalPath
, versionName
);
404 if (prevVersionRoaming
!= "")
405 userRoamingPathPrevVersion
= Path
.Combine(userRoamingPath
, prevVersionRoaming
);
406 if (prevVersionLocal
!= "")
407 userLocalPathPrevVersion
= Path
.Combine(userLocalPath
, prevVersionLocal
);
410 // string for the previous version. It ignores newer ones.
411 private static string PrevVersionPath (string dirName
, string currentVersion
)
413 string prevVersionString
= "";
415 if (!Directory
.Exists(dirName
))
416 return prevVersionString
;
417 DirectoryInfo currentDir
= new DirectoryInfo (dirName
);
418 foreach (DirectoryInfo dirInfo
in currentDir
.GetDirectories ())
419 if (String
.Compare (currentVersion
, dirInfo
.Name
, StringComparison
.Ordinal
) > 0)
420 if (String
.Compare (prevVersionString
, dirInfo
.Name
, StringComparison
.Ordinal
) < 0)
421 prevVersionString
= dirInfo
.Name
;
423 return prevVersionString
;
426 // sets the explicit path to store roaming user.config or equivalent.
427 // (returns the path validity.)
428 public static bool SetUserRoamingPath (string configPath
)
430 if (CheckPath (configPath
))
432 userRoamingBasePath
= configPath
;
439 // sets the explicit path to store local user.config or equivalent.
440 // (returns the path validity.)
441 public static bool SetUserLocalPath (string configPath
)
443 if (CheckPath (configPath
))
445 userLocalBasePath
= configPath
;
452 private static bool CheckFileName (string configFile
)
455 char[] invalidFileChars = Path.GetInvalidFileNameChars();
457 foreach (char invalidChar in invalidFileChars)
459 if (configFile.Contains(invalidChar.ToString()))
466 return configFile
.IndexOfAny (Path
.GetInvalidFileNameChars ()) < 0;
469 // sets the explicit roaming file name which is user.config equivalent.
470 // (returns the file name validity.)
471 public static bool SetUserRoamingFileName (string configFile
)
473 if (CheckFileName (configFile
))
475 userRoamingName
= configFile
;
482 // sets the explicit local file name which is user.config equivalent.
483 // (returns the file name validity.)
484 public static bool SetUserLocalFileName (string configFile
)
486 if (CheckFileName (configFile
))
488 userLocalName
= configFile
;
495 // sets the explicit company name for folder.
496 // (returns the file name validity.)
497 public static bool SetCompanyName (string companyName
)
499 if (CheckFileName (companyName
))
501 CompanyName
= companyName
;
508 // sets the explicit product name for folder.
509 // (returns the file name validity.)
510 public static bool SetProductName (string productName
)
512 if (CheckFileName (productName
))
514 ProductName
= productName
;
521 // sets the explicit major version for folder.
522 public static bool SetVersion (int major
)
524 ForceVersion
= string.Format ("{0}", major
);
528 // sets the explicit major and minor versions for folder.
529 public static bool SetVersion (int major
, int minor
)
531 ForceVersion
= string.Format ("{0}.{1}", major
, minor
);
535 // sets the explicit major/minor/build numbers for folder.
536 public static bool SetVersion (int major
, int minor
, int build
)
538 ForceVersion
= string.Format ("{0}.{1}.{2}", major
, minor
, build
);
542 // sets the explicit major/minor/build/revision numbers for folder.
543 public static bool SetVersion (int major
, int minor
, int build
, int revision
)
545 ForceVersion
= string.Format ("{0}.{1}.{2}.{3}", major
, minor
, build
, revision
);
549 // sets the explicit version number string for folder.
550 public static bool SetVersion (string forceVersion
)
552 if (CheckFileName (forceVersion
))
554 ForceVersion
= forceVersion
;
561 private static bool CheckPath (string configPath
)
563 char[] invalidPathChars
= Path
.GetInvalidPathChars ();
566 foreach (char invalidChar in invalidPathChars)
568 if (configPath.Contains (invalidChar.ToString()))
574 if (configPath
.IndexOfAny (invalidPathChars
) >= 0)
577 string folder
= configPath
;
579 while ((fileName
= Path
.GetFileName (folder
)) != "")
581 if (!CheckFileName (fileName
))
585 folder
= Path
.GetDirectoryName (folder
);
592 public override string Name
{
593 get { return base.Name; }
596 string app_name
= String
.Empty
;//"OJK.CustomSetting.CustomizableLocalFileSettingsProvider";
597 public override string ApplicationName
{
598 get { return app_name; }
599 set { app_name = value; }
602 private ExeConfigurationFileMap exeMapCurrent
= null;
603 private ExeConfigurationFileMap exeMapPrev
= null;
604 private SettingsPropertyValueCollection values
= null;
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 true // my reimplementation
615 if (userGroup
== null) {
616 userGroup
= new UserSettingsGroup ();
617 config
.SectionGroups
.Add ("userSettings", userGroup
);
618 ApplicationSettingsBase asb
= context
.CurrentSettings
;
619 ClientSettingsSection cs
= new ClientSettingsSection ();
620 string class_name
= NormalizeInvalidXmlChars ((asb
!= null ? asb
.GetType () : typeof (ApplicationSettingsBase
)).FullName
);
621 userGroup
.Sections
.Add (class_name
, cs
);
624 bool hasChanges
= false;
626 foreach (ConfigurationSection section
in userGroup
.Sections
) {
627 ClientSettingsSection userSection
= section
as ClientSettingsSection
;
628 if (userSection
== null)
631 foreach (SettingsPropertyValue
value in collection
) {
632 if (checkUserLevel
&& value.Property
.Attributes
.Contains (typeof (SettingsManageabilityAttribute
)) != isRoaming
)
634 // The default impl does not save the ApplicationScopedSetting properties
635 if (value.Property
.Attributes
.Contains (typeof (ApplicationScopedSettingAttribute
)))
639 SettingElement element
= userSection
.Settings
.Get (value.Name
);
640 if (element
== null) {
641 element
= new SettingElement (value.Name
, value.Property
.SerializeAs
);
642 userSection
.Settings
.Add (element
);
644 if (element
.Value
.ValueXml
== null)
645 element
.Value
.ValueXml
= new XmlDocument ().CreateElement ("value");
646 switch (value.Property
.SerializeAs
) {
647 case SettingsSerializeAs
.Xml
:
648 element
.Value
.ValueXml
.InnerXml
= (value.SerializedValue
as string) ?? string.Empty
;
650 case SettingsSerializeAs
.String
:
651 element
.Value
.ValueXml
.InnerText
= value.SerializedValue
as string;
653 case SettingsSerializeAs
.Binary
:
654 element
.Value
.ValueXml
.InnerText
= value.SerializedValue
!= null ? Convert
.ToBase64String (value.SerializedValue
as byte []) : string.Empty
;
657 throw new NotImplementedException ();
662 config
.Save (ConfigurationSaveMode
.Minimal
, true);
664 #else // original impl. - likely buggy to miss some properties to save
666 foreach (ConfigurationSection configSection
in userGroup
.Sections
)
668 ClientSettingsSection userSection
= configSection
as ClientSettingsSection
;
669 if (userSection
!= null)
672 userSection.Settings.Clear();
674 foreach (SettingsPropertyValue propertyValue in collection)
676 if (propertyValue.IsDirty)
678 SettingElement element = new SettingElement(propertyValue.Name, SettingsSerializeAs.String);
679 element.Value.ValueXml = new XmlDocument();
680 element.Value.ValueXml.InnerXml = (string)propertyValue.SerializedValue;
681 userSection.Settings.Add(element);
685 foreach (SettingElement element
in userSection
.Settings
)
687 if (collection
[element
.Name
] != null) {
688 if (collection
[element
.Name
].Property
.Attributes
.Contains (typeof (SettingsManageabilityAttribute
)) != isRoaming
)
691 element
.SerializeAs
= SettingsSerializeAs
.String
;
692 element
.Value
.ValueXml
.InnerXml
= (string) collection
[element
.Name
].SerializedValue
; ///Value = XmlElement
698 config
.Save (ConfigurationSaveMode
.Minimal
, true);
702 // NOTE: We should add here all the chars that are valid in a name of a class (Ecma-wise),
703 // but invalid in an xml element name, and provide a better impl if we get too many of them.
704 string NormalizeInvalidXmlChars (string str
)
706 char [] invalid_chars
= new char [] { '+' }
;
708 if (str
== null || str
.IndexOfAny (invalid_chars
) == -1)
711 // Replace with its hexadecimal values.
712 str
= str
.Replace ("+", "_x002B_");
716 private void LoadPropertyValue (SettingsPropertyCollection collection
, SettingElement element
, bool allowOverwrite
)
718 SettingsProperty prop
= collection
[element
.Name
];
719 if (prop
== null) { // see bug #343459
720 prop
= new SettingsProperty (element
.Name
);
721 collection
.Add (prop
);
724 SettingsPropertyValue
value = new SettingsPropertyValue (prop
);
725 value.IsDirty
= false;
726 if (element
.Value
.ValueXml
!= null) {
727 switch (value.Property
.SerializeAs
) {
728 case SettingsSerializeAs
.Xml
:
729 value.SerializedValue
= element
.Value
.ValueXml
.InnerXml
;
731 case SettingsSerializeAs
.String
:
732 value.SerializedValue
= element
.Value
.ValueXml
.InnerText
;
734 case SettingsSerializeAs
.Binary
:
735 value.SerializedValue
= Convert
.FromBase64String (element
.Value
.ValueXml
.InnerText
);
740 value.SerializedValue
= prop
.DefaultValue
;
744 values
.Remove (element
.Name
);
746 } catch (ArgumentException ex
) {
747 throw new ConfigurationErrorsException (string.Format (
748 CultureInfo
.InvariantCulture
,
749 "Failed to load value for '{0}'.",
754 private void LoadProperties (ExeConfigurationFileMap exeMap
, SettingsPropertyCollection collection
, ConfigurationUserLevel level
, string sectionGroupName
, bool allowOverwrite
, string groupName
)
756 Configuration config
= ConfigurationManager
.OpenMappedExeConfiguration (exeMap
,level
);
758 ConfigurationSectionGroup sectionGroup
= config
.GetSectionGroup (sectionGroupName
);
759 if (sectionGroup
!= null) {
760 foreach (ConfigurationSection configSection
in sectionGroup
.Sections
) {
761 if (configSection
.SectionInformation
.Name
!= groupName
)
764 ClientSettingsSection clientSection
= configSection
as ClientSettingsSection
;
765 if (clientSection
== null)
768 foreach (SettingElement element
in clientSection
.Settings
) {
769 LoadPropertyValue(collection
, element
, allowOverwrite
);
771 // Only the first one seems to be processed by MS
778 public override void SetPropertyValues (SettingsContext context
, SettingsPropertyValueCollection collection
)
782 if (UserLocalFullPath
== UserRoamingFullPath
)
784 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, context
, false);
786 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, context
, true);
787 SaveProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoamingAndLocal
, context
, true);
791 public override SettingsPropertyValueCollection
GetPropertyValues (SettingsContext context
, SettingsPropertyCollection collection
)
795 if (values
== null) {
796 values
= new SettingsPropertyValueCollection ();
797 string groupName
= context
["GroupName"] as string;
798 groupName
= NormalizeInvalidXmlChars (groupName
); // we likely saved the element removing the non valid xml chars.
799 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.None
, "applicationSettings", false, groupName
);
800 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.None
, "userSettings", false, groupName
);
802 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoaming
, "userSettings", true, groupName
);
803 LoadProperties (exeMapCurrent
, collection
, ConfigurationUserLevel
.PerUserRoamingAndLocal
, "userSettings", true, groupName
);
805 // create default values if not exist
806 foreach (SettingsProperty p
in collection
)
807 if (values
[p
.Name
] == null)
808 values
.Add (new SettingsPropertyValue (p
));
813 /// creates an ExeConfigurationFileMap
814 private void CreateExeMap ()
816 if (exeMapCurrent
== null) {
817 CreateUserConfigPath ();
820 exeMapCurrent
= new ExeConfigurationFileMap ();
822 // exeMapCurrent.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
823 Assembly entry
= Assembly
.GetEntryAssembly () ?? Assembly
.GetExecutingAssembly ();
824 exeMapCurrent
.ExeConfigFilename
= entry
.Location
+ ".config";
825 exeMapCurrent
.LocalUserConfigFilename
= UserLocalFullPath
;
826 exeMapCurrent
.RoamingUserConfigFilename
= UserRoamingFullPath
;
828 if (webConfigurationFileMapType
!= null && typeof (ConfigurationFileMap
).IsAssignableFrom (webConfigurationFileMapType
)) {
830 ConfigurationFileMap cfgFileMap
= Activator
.CreateInstance (webConfigurationFileMapType
) as ConfigurationFileMap
;
831 if (cfgFileMap
!= null) {
832 string fpath
= cfgFileMap
.MachineConfigFilename
;
833 if (!String
.IsNullOrEmpty (fpath
))
834 exeMapCurrent
.ExeConfigFilename
= fpath
;
842 if ((PrevUserLocalFullPath
!= "") && (PrevUserRoamingFullPath
!= ""))
844 exeMapPrev
= new ExeConfigurationFileMap();
845 // exeMapPrev.ExeConfigFilename = System.Windows.Forms.Application.ExecutablePath + ".config";
846 exeMapPrev
.ExeConfigFilename
= entry
.Location
+ ".config";
847 exeMapPrev
.LocalUserConfigFilename
= PrevUserLocalFullPath
;
848 exeMapPrev
.RoamingUserConfigFilename
= PrevUserRoamingFullPath
;
854 public SettingsPropertyValue
GetPreviousVersion (SettingsContext context
, SettingsProperty property
)
859 public void Reset (SettingsContext context
)
861 SettingsPropertyCollection coll
= new SettingsPropertyCollection ();
862 GetPropertyValues (context
, coll
);
863 foreach (SettingsPropertyValue propertyValue
in values
) {
864 // Can't use propertyValue.Property.DefaultValue
865 // as it may cause InvalidCastException (see bug# 532180)
866 propertyValue
.PropertyValue
= propertyValue
.Reset ();
868 SetPropertyValues (context
, values
);
872 public void Upgrade (SettingsContext context
, SettingsPropertyCollection properties
)
876 public static void setCreate ()
878 CreateUserConfigPath();