Utilities/PersistentSettings.cs
author moel.mich
Tue, 30 Dec 2014 17:35:29 +0000
changeset 429 5d87c9fc69f6
parent 344 3145aadca3d2
permissions -rw-r--r--
Changed the settings save code to use a two file based approach in order to reduce cases where settings are lost or reset (Fixed Issue 501).
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2009-2014 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System.Collections.Generic;
    12 using System.Drawing;
    13 using System.Globalization;
    14 using System.IO;
    15 using System.Text;
    16 using System.Xml;
    17 using OpenHardwareMonitor.Hardware;
    18 
    19 namespace OpenHardwareMonitor {
    20   public class PersistentSettings : ISettings {
    21 
    22     private IDictionary<string, string> settings = 
    23       new Dictionary<string, string>();
    24 
    25     public void Load(string fileName) {
    26       XmlDocument doc = new XmlDocument();
    27       try {
    28         doc.Load(fileName);
    29       } catch {
    30         try {
    31           File.Delete(fileName);
    32         } catch { }
    33 
    34         string backupFileName = fileName + ".backup";
    35         try {
    36           doc.Load(backupFileName);
    37         } catch {
    38           try {
    39             File.Delete(backupFileName);
    40           } catch { }
    41 
    42           return;
    43         }
    44       }
    45 
    46       XmlNodeList list = doc.GetElementsByTagName("appSettings");
    47       foreach (XmlNode node in list) {
    48         XmlNode parent = node.ParentNode;
    49         if (parent != null && parent.Name == "configuration" && 
    50           parent.ParentNode is XmlDocument) {
    51           foreach (XmlNode child in node.ChildNodes) {
    52             if (child.Name == "add") {
    53               XmlAttributeCollection attributes = child.Attributes;
    54               XmlAttribute keyAttribute = attributes["key"];
    55               XmlAttribute valueAttribute = attributes["value"];
    56               if (keyAttribute != null && valueAttribute != null && 
    57                 keyAttribute.Value != null) {
    58                 settings.Add(keyAttribute.Value, valueAttribute.Value);
    59               }
    60             }
    61           }
    62         }
    63       }
    64     }
    65 
    66     public void Save(string fileName) {
    67 
    68       XmlDocument doc = new XmlDocument();
    69       doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
    70       XmlElement configuration = doc.CreateElement("configuration");
    71       doc.AppendChild(configuration);
    72       XmlElement appSettings = doc.CreateElement("appSettings");
    73       configuration.AppendChild(appSettings);
    74       foreach (KeyValuePair<string, string> keyValuePair in settings) {
    75         XmlElement add = doc.CreateElement("add");
    76         add.SetAttribute("key", keyValuePair.Key);
    77         add.SetAttribute("value", keyValuePair.Value);
    78         appSettings.AppendChild(add);
    79       }
    80 
    81       byte[] file;
    82       using (var memory = new MemoryStream()) {
    83         using (var writer = new StreamWriter(memory, Encoding.UTF8)) {
    84           doc.Save(writer);
    85         }
    86         file = memory.ToArray();
    87       }
    88 
    89       string backupFileName = fileName + ".backup";
    90       if (File.Exists(fileName)) {
    91         try {
    92           File.Delete(backupFileName);
    93         } catch { }
    94         try {
    95           File.Move(fileName, backupFileName);
    96         } catch { }
    97       }
    98 
    99       using (var stream = new FileStream(fileName, 
   100         FileMode.Create, FileAccess.Write))
   101       {
   102         stream.Write(file, 0, file.Length);
   103       }
   104 
   105       try {
   106         File.Delete(backupFileName);
   107       } catch { }
   108     }
   109 
   110     public bool Contains(string name) {
   111       return settings.ContainsKey(name);
   112     }
   113 
   114     public void SetValue(string name, string value) {
   115       settings[name] = value;
   116     }
   117 
   118     public string GetValue(string name, string value) {
   119       string result;
   120       if (settings.TryGetValue(name, out result))
   121         return result;
   122       else
   123         return value;
   124     }
   125 
   126     public void Remove(string name) {
   127       settings.Remove(name);
   128     }
   129 
   130     public void SetValue(string name, int value) {
   131       settings[name] = value.ToString();
   132     }
   133 
   134     public int GetValue(string name, int value) {
   135       string str;
   136       if (settings.TryGetValue(name, out str)) {
   137         int parsedValue;
   138         if (int.TryParse(str, out parsedValue))
   139           return parsedValue;
   140         else
   141           return value;
   142       } else {
   143         return value;
   144       }
   145     }
   146 
   147     public void SetValue(string name, float value) {
   148       settings[name] = value.ToString(CultureInfo.InvariantCulture);
   149     }
   150 
   151     public float GetValue(string name, float value) {
   152       string str;
   153       if (settings.TryGetValue(name, out str)) {
   154         float parsedValue;
   155         if (float.TryParse(str, NumberStyles.Float, 
   156           CultureInfo.InvariantCulture, out parsedValue))
   157           return parsedValue;
   158         else
   159           return value;
   160       } else {
   161         return value;
   162       }
   163     }
   164 
   165     public void SetValue(string name, bool value) {
   166       settings[name] = value ? "true" : "false";
   167     }
   168 
   169     public bool GetValue(string name, bool value) {
   170       string str;
   171       if (settings.TryGetValue(name, out str)) {
   172         return str == "true";
   173       } else {
   174         return value;
   175       }
   176     }
   177 
   178     public void SetValue(string name, Color color) {
   179       settings[name] = color.ToArgb().ToString("X8");
   180     }
   181 
   182     public Color GetValue(string name, Color value) {
   183       string str;
   184       if (settings.TryGetValue(name, out str)) {
   185         int parsedValue;
   186         if (int.TryParse(str, NumberStyles.HexNumber,
   187           CultureInfo.InvariantCulture, out parsedValue))
   188           return Color.FromArgb(parsedValue);
   189         else
   190           return value;
   191       } else {
   192         return value;
   193       }
   194     }
   195   }
   196 }