snap-2-html/Snap2HTML/PortableSettingsProvider.cs
2025-02-28 16:11:48 -07:00

244 lines
7.6 KiB
C#

// Source: http://www.codeproject.com/Articles/20917/Creating-a-Custom-Settings-Provider , License: The Code Project Open License (CPOL)
// To use: For each setting in properties: Properties->Provider set to PortableSettingsProvider
// If this does not compile: Project->Add Reference->.Net-> Doubleclick "System.Configuration"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Win32;
public class PortableSettingsProvider : SettingsProvider
{
const string SETTINGSROOT = "Settings";
//XML Root Node
public override void Initialize(string name, NameValueCollection col)
{
base.Initialize(this.ApplicationName, col);
}
public override string ApplicationName
{
get
{
if (Application.ProductName.Trim().Length > 0)
{
return Application.ProductName;
}
else
{
FileInfo fi = new FileInfo(Application.ExecutablePath);
return fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length);
}
}
set { }
//Do nothing
}
public override string Name
{
get { return "PortableSettingsProvider"; }
}
public virtual string GetAppSettingsPath()
{
//Used to determine where to store the settings
System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
return fi.DirectoryName;
}
public virtual string GetAppSettingsFilename()
{
//Used to determine the filename to store the settings
return ApplicationName + ".settings";
}
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
{
//Iterate through the settings to be stored
//Only dirty settings are included in propvals, and only ones relevant to this provider
foreach (SettingsPropertyValue propval in propvals)
{
SetValue(propval);
}
try
{
SettingsXML.Save(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename()));
}
catch (Exception)
{
}
//Ignore if cant save, device been ejected
}
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 = GetValue(setting);
values.Add(value);
}
return values;
}
private XmlDocument _settingsXML = null;
private XmlDocument SettingsXML
{
get
{
//If we dont hold an xml document, try opening one.
//If it doesnt exist then create a new one ready.
if (_settingsXML == null)
{
_settingsXML = new XmlDocument();
try
{
_settingsXML.Load(Path.Combine(GetAppSettingsPath(), GetAppSettingsFilename()));
}
catch (Exception)
{
//Create new document
XmlDeclaration dec = _settingsXML.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
_settingsXML.AppendChild(dec);
XmlNode nodeRoot = default(XmlNode);
nodeRoot = _settingsXML.CreateNode(XmlNodeType.Element, SETTINGSROOT, "");
_settingsXML.AppendChild(nodeRoot);
}
}
return _settingsXML;
}
}
private string GetValue(SettingsProperty setting)
{
string ret = "";
try
{
if (IsRoaming(setting))
{
ret = SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + setting.Name).InnerText;
}
else
{
ret = SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + setting.Name).InnerText;
}
}
catch (Exception)
{
if ((setting.DefaultValue != null))
{
ret = setting.DefaultValue.ToString();
}
else
{
ret = "";
}
}
return ret;
}
private void SetValue(SettingsPropertyValue propVal)
{
XmlElement MachineNode = default(XmlElement);
XmlElement SettingNode = default(XmlElement);
//Determine if the setting is roaming.
//If roaming then the value is stored as an element under the root
//Otherwise it is stored under a machine name node
try
{
if (IsRoaming(propVal.Property))
{
SettingNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + propVal.Name);
}
else
{
SettingNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName + "/" + propVal.Name);
}
}
catch (Exception)
{
SettingNode = null;
}
//Check to see if the node exists, if so then set its new value
if ((SettingNode != null))
{
SettingNode.InnerText = propVal.SerializedValue.ToString();
}
else
{
if (IsRoaming(propVal.Property))
{
//Store the value as an element of the Settings Root Node
SettingNode = SettingsXML.CreateElement(propVal.Name);
SettingNode.InnerText = propVal.SerializedValue.ToString();
SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(SettingNode);
}
else
{
//Its machine specific, store as an element of the machine name node,
//creating a new machine name node if one doesnt exist.
try
{
MachineNode = (XmlElement)SettingsXML.SelectSingleNode(SETTINGSROOT + "/" + Environment.MachineName);
}
catch (Exception)
{
MachineNode = SettingsXML.CreateElement(Environment.MachineName);
SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
if (MachineNode == null)
{
MachineNode = SettingsXML.CreateElement(Environment.MachineName);
SettingsXML.SelectSingleNode(SETTINGSROOT).AppendChild(MachineNode);
}
SettingNode = SettingsXML.CreateElement(propVal.Name);
SettingNode.InnerText = propVal.SerializedValue.ToString();
MachineNode.AppendChild(SettingNode);
}
}
}
private bool IsRoaming(SettingsProperty prop)
{
//Determine if the setting is marked as Roaming
foreach (DictionaryEntry d in prop.Attributes)
{
Attribute a = (Attribute)d.Value;
if (a is System.Configuration.SettingsManageabilityAttribute)
{
return true;
}
}
return false;
}
}