Advertisement
fortsoft

PersistentSettings

Sep 1st, 2020 (edited)
1,305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 20.62 KB | Source Code | 0 0
  1. /**
  2.  * This is open-source software licensed under the terms of the MIT License.
  3.  *
  4.  * Copyright (c) 2009-2023 Petr Červinka - FortSoft <[email protected]>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7.  * of this software and associated documentation files (the "Software"), to deal
  8.  * in the Software without restriction, including without limitation the rights
  9.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.  * copies of the Software, and to permit persons to whom the Software is
  11.  * furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in all
  14.  * copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  **
  24.  * Version 2.0.1.0
  25.  */
  26.  
  27. using Microsoft.Win32;
  28. using System;
  29. using System.ComponentModel;
  30. using System.Diagnostics;
  31. using System.Drawing;
  32. using System.Globalization;
  33. using System.IO;
  34. using System.Security;
  35. using System.Windows.Forms;
  36.  
  37. namespace FortSoft.Tools {
  38.  
  39.     /// <summary>
  40.     /// Implements saving the values of the software application in the Windows
  41.     /// registry for later use. Also implements reading previously saved values
  42.     /// from the Windows registry.
  43.     /// Supported datatypes are: sbyte (System.SByte), byte (System.Byte), short
  44.     /// (System.Int16), ushort (System.UInt16), int (System.Int32), uint
  45.     /// (System.UInt32), long (System.Int64), ulong (System.UInt64), char
  46.     /// (System.Char), float (System.Single), double (System.Double), bool
  47.     /// (System.Boolean), decimal (System.Decimal), string (System.String),
  48.     /// DateTime (System.DateTime), TimeSpan (System.TimeSpan), Color
  49.     /// (System.Drawing.Color).
  50.     /// Datatypes not listed above may work, but the class is not ready for them.
  51.     /// </summary>
  52.     public sealed class PersistentSettings : Component {
  53.  
  54.         /// <summary>
  55.         /// Constants
  56.         /// </summary>
  57.         private const string Software = "Software";
  58.  
  59.         /// <summary>
  60.         /// Fields
  61.         /// </summary>
  62.         private string registryPath;
  63.         private RegistryKey registryKeyReadOnly, registryKeyWritable;
  64.  
  65.         /// <summary>
  66.         /// Events
  67.         /// </summary>
  68.         public event EventHandler<PersistentSettingsEventArgs> Error;
  69.         public event EventHandler<PersistentSettingsEventArgs> Loaded;
  70.         public event EventHandler<PersistentSettingsEventArgs> Saved;
  71.  
  72.         /// <summary>
  73.         /// Initializes a new instance of the <see cref="PersistentSettings"/>
  74.         /// class.
  75.         /// </summary>
  76.         public PersistentSettings() {
  77.             registryPath = Path.Combine(Software, Application.CompanyName, Application.ProductName);
  78.         }
  79.  
  80.         /// <summary>
  81.         /// Gets Windows registry subtree path.
  82.         /// </summary>
  83.         public string RegistryPath { get; private set; }
  84.  
  85.         /// <summary>
  86.         /// Clears the application subtree in the Windows registry.
  87.         /// </summary>
  88.         public void Clear() {
  89.             try {
  90.                 Registry.CurrentUser.DeleteSubKeyTree(registryPath);
  91.             } catch (Exception exception) {
  92.                 Debug.WriteLine(exception);
  93.             }
  94.         }
  95.  
  96.         /// <summary>
  97.         /// Clean up any resources being used.
  98.         /// </summary>
  99.         /// <param name="disposing">true if managed resources should be disposed;
  100.         /// otherwise, false.</param>
  101.         protected override void Dispose(bool disposing) {
  102.             if (disposing) {
  103.                 if (registryKeyReadOnly != null) {
  104.                     registryKeyReadOnly.Dispose();
  105.                 }
  106.                 if (registryKeyWritable != null) {
  107.                     registryKeyWritable.Dispose();
  108.                 }
  109.             }
  110.             base.Dispose(disposing);
  111.         }
  112.  
  113.         /// <summary>
  114.         /// Loads the value from the Windows registry. Supported datatypes are:
  115.         /// sbyte (System.SByte), byte (System.Byte), short (System.Int16),
  116.         /// ushort (System.UInt16), int (System.Int32), uint (System.UInt32),
  117.         /// long (System.Int64), ulong (System.UInt64), char (System.Char),
  118.         /// float (System.Single), double (System.Double), bool (System.Boolean),
  119.         /// decimal (System.Decimal), string (System.String), DateTime
  120.         /// (System.DateTime), TimeSpan (System.TimeSpan), Color
  121.         /// (System.Drawing.Color). Datatypes not listed here may work, but their
  122.         /// support is not implemented.
  123.         /// <param name="valueName">Name of the value.</param>
  124.         /// </summary>
  125.         public T Load<T>(string valueName) {
  126.             try {
  127.                 if (registryKeyReadOnly == null) {
  128.                     registryKeyReadOnly = Registry.CurrentUser.OpenSubKey(registryPath);
  129.                 }
  130.                 if (registryKeyReadOnly != null) {
  131.                     object value = registryKeyReadOnly.GetValue(valueName, null);
  132.                     Loaded?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly));
  133.                     if (typeof(T) == typeof(bool)) {
  134.                         return (T)Convert.ChangeType((int)value > 0, typeof(T));
  135.                     }
  136.                     if (typeof(T) == typeof(byte)) {
  137.                         return (T)Convert.ChangeType((byte)unchecked((int)value), typeof(T));
  138.                     }
  139.                     if (typeof(T) == typeof(Color)) {
  140.                         return (T)Convert.ChangeType(Color.FromArgb((int)value), typeof(T));
  141.                     }
  142.                     if (typeof(T) == typeof(DateTime)) {
  143.                         return (T)Convert.ChangeType(DateTime.FromBinary((long)value), typeof(T));
  144.                     }
  145.                     if (typeof(T) == typeof(decimal)) {
  146.                         return (T)Convert.ChangeType(decimal.Parse((string)value, CultureInfo.InvariantCulture), typeof(T));
  147.                     }
  148.                     if (typeof(T) == typeof(double)) {
  149.                         return (T)Convert.ChangeType(BitConverter.Int64BitsToDouble((long)value), typeof(T));
  150.                     }
  151.                     if (typeof(T) == typeof(float)) {
  152.                         return (T)Convert.ChangeType(BitConverter.ToSingle(BitConverter.GetBytes((int)value), 0), typeof(T));
  153.                     }
  154.                     if (typeof(T) == typeof(TimeSpan)) {
  155.                         return (T)Convert.ChangeType(TimeSpan.FromTicks((long)value), typeof(T));
  156.                     }
  157.                     if (typeof(T) == typeof(uint)) {
  158.                         return (T)Convert.ChangeType((uint)unchecked((int)value), typeof(T));
  159.                     }
  160.                     if (typeof(T) == typeof(ulong)) {
  161.                         return (T)Convert.ChangeType((ulong)unchecked((long)value), typeof(T));
  162.                     }
  163.                     if (typeof(T) == typeof(ushort)) {
  164.                         return (T)Convert.ChangeType((ushort)unchecked((int)value), typeof(T));
  165.                     }
  166.                     return (T)Convert.ChangeType(value, typeof(T));
  167.                 }
  168.             } catch (IOException exception) {
  169.                 Debug.WriteLine(exception);
  170.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly, exception));
  171.             } catch (SecurityException exception) {
  172.                 Debug.WriteLine(exception);
  173.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly, exception));
  174.             } catch (Exception exception) {
  175.                 Debug.WriteLine(exception);
  176.             }
  177.             return default(T);
  178.         }
  179.  
  180.         /// <summary>
  181.         /// Loads the value from the Windows registry. If the value is not found
  182.         /// in the Windows registry, returns the default value. Supported
  183.         /// datatypes are: sbyte (System.SByte), byte (System.Byte), short
  184.         /// (System.Int16), ushort (System.UInt16), int (System.Int32), uint
  185.         /// (System.UInt32), long (System.Int64), ulong (System.UInt64), char
  186.         /// (System.Char), float (System.Single), double (System.Double), bool
  187.         /// (System.Boolean), decimal (System.Decimal), string (System.String),
  188.         /// DateTime (System.DateTime), TimeSpan (System.TimeSpan), Color
  189.         /// (System.Drawing.Color). Datatypes not listed here may work, but their
  190.         /// support is not implemented.
  191.         /// <param name="valueName">Name of the value.</param>
  192.         /// <param name="defaultValue">Default value.</param>
  193.         /// </summary>
  194.         public T Load<T>(string valueName, T defaultValue) {
  195.             try {
  196.                 if (registryKeyReadOnly == null) {
  197.                     registryKeyReadOnly = Registry.CurrentUser.OpenSubKey(registryPath);
  198.                 }
  199.                 if (registryKeyReadOnly != null) {
  200.                     object defaultVal;
  201.                     if (typeof(T) == typeof(bool)) {
  202.                         defaultVal = (bool)Convert.ChangeType(defaultValue, typeof(T)) ? 1 : 0;
  203.                     } else if (typeof(T) == typeof(byte)) {
  204.                         defaultVal = (int)checked((byte)Convert.ChangeType(defaultValue, typeof(T)));
  205.                     } else if (typeof(T) == typeof(char)) {
  206.                         defaultVal = (int)(char)Convert.ChangeType(defaultValue, typeof(T));
  207.                     } else if (typeof(T) == typeof(Color)) {
  208.                         defaultVal = ((Color)Convert.ChangeType(defaultValue, typeof(T))).ToArgb();
  209.                     } else if (typeof(T) == typeof(DateTime)) {
  210.                         defaultVal = ((DateTime)Convert.ChangeType(defaultValue, typeof(T))).ToBinary();
  211.                     } else if (typeof(T) == typeof(decimal)) {
  212.                         defaultVal = ((decimal)Convert.ChangeType(defaultValue, typeof(T))).ToString(CultureInfo.InvariantCulture);
  213.                     } else if (typeof(T) == typeof(double)) {
  214.                         defaultVal = BitConverter.DoubleToInt64Bits((double)Convert.ChangeType(defaultValue, typeof(T)));
  215.                     } else if (typeof(T) == typeof(float)) {
  216.                         defaultVal = BitConverter.ToInt32(BitConverter.GetBytes((float)Convert.ChangeType(defaultValue, typeof(T))), 0);
  217.                     } else if (typeof(T) == typeof(int)) {
  218.                         defaultVal = (int)Convert.ChangeType(defaultValue, typeof(T));
  219.                     } else if (typeof(T) == typeof(long)) {
  220.                         defaultVal = (long)Convert.ChangeType(defaultValue, typeof(T));
  221.                     } else if (typeof(T) == typeof(sbyte)) {
  222.                         defaultVal = (int)(sbyte)Convert.ChangeType(defaultValue, typeof(T));
  223.                     } else if (typeof(T) == typeof(short)) {
  224.                         defaultVal = (int)(short)Convert.ChangeType(defaultValue, typeof(T));
  225.                     } else if (typeof(T) == typeof(TimeSpan)) {
  226.                         defaultVal = ((TimeSpan)Convert.ChangeType(defaultValue, typeof(T))).Ticks;
  227.                     } else if (typeof(T) == typeof(uint)) {
  228.                         defaultVal = (int)checked((uint)Convert.ChangeType(defaultValue, typeof(T)));
  229.                     } else if (typeof(T) == typeof(ulong)) {
  230.                         defaultVal = (long)checked((ulong)Convert.ChangeType(defaultValue, typeof(T)));
  231.                     } else if (typeof(T) == typeof(ushort)) {
  232.                         defaultVal = (int)checked((ushort)Convert.ChangeType(defaultValue, typeof(T)));
  233.                     } else {
  234.                         defaultVal = defaultValue;
  235.                     }
  236.                     object value = registryKeyReadOnly.GetValue(valueName, defaultVal);
  237.                     Loaded?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly));
  238.                     if (typeof(T) == typeof(bool)) {
  239.                         return (T)Convert.ChangeType((int)value > 0, typeof(T));
  240.                     }
  241.                     if (typeof(T) == typeof(byte)) {
  242.                         return (T)Convert.ChangeType((byte)unchecked((int)value), typeof(T));
  243.                     }
  244.                     if (typeof(T) == typeof(Color)) {
  245.                         return (T)Convert.ChangeType(Color.FromArgb((int)value), typeof(T));
  246.                     }
  247.                     if (typeof(T) == typeof(DateTime)) {
  248.                         return (T)Convert.ChangeType(DateTime.FromBinary((long)value), typeof(T));
  249.                     }
  250.                     if (typeof(T) == typeof(decimal)) {
  251.                         return (T)Convert.ChangeType(decimal.Parse((string)value, CultureInfo.InvariantCulture), typeof(T));
  252.                     }
  253.                     if (typeof(T) == typeof(double)) {
  254.                         return (T)Convert.ChangeType(BitConverter.Int64BitsToDouble((long)value), typeof(T));
  255.                     }
  256.                     if (typeof(T) == typeof(float)) {
  257.                         return (T)Convert.ChangeType(BitConverter.ToSingle(BitConverter.GetBytes((int)value), 0), typeof(T));
  258.                     }
  259.                     if (typeof(T) == typeof(TimeSpan)) {
  260.                         return (T)Convert.ChangeType(TimeSpan.FromTicks((long)value), typeof(T));
  261.                     }
  262.                     if (typeof(T) == typeof(uint)) {
  263.                         return (T)Convert.ChangeType((uint)unchecked((int)value), typeof(T));
  264.                     }
  265.                     if (typeof(T) == typeof(ulong)) {
  266.                         return (T)Convert.ChangeType((ulong)unchecked((long)value), typeof(T));
  267.                     }
  268.                     if (typeof(T) == typeof(ushort)) {
  269.                         return (T)Convert.ChangeType((ushort)unchecked((int)value), typeof(T));
  270.                     }
  271.                     return (T)Convert.ChangeType(value, typeof(T));
  272.                 }
  273.             } catch (IOException exception) {
  274.                 Debug.WriteLine(exception);
  275.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly, exception));
  276.             } catch (SecurityException exception) {
  277.                 Debug.WriteLine(exception);
  278.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyReadOnly, exception));
  279.             } catch (Exception exception) {
  280.                 Debug.WriteLine(exception);
  281.             }
  282.             return defaultValue;
  283.         }
  284.  
  285.         /// <summary>
  286.         /// Saves the value into the Windows registry. Supported datatypes are:
  287.         /// sbyte (System.SByte), byte (System.Byte), short (System.Int16),
  288.         /// ushort (System.UInt16), int (System.Int32), uint (System.UInt32),
  289.         /// long (System.Int64), ulong (System.UInt64), char (System.Char),
  290.         /// float (System.Single), double (System.Double), bool (System.Boolean),
  291.         /// decimal (System.Decimal), string (System.String), DateTime
  292.         /// (System.DateTime), TimeSpan (System.TimeSpan), Color
  293.         /// (System.Drawing.Color). Datatypes not listed here may work, but their
  294.         /// support is not implemented.
  295.         /// </summary>
  296.         /// <param name="valueName">Name of the value.</param>
  297.         /// <param name="value">Value to save.</param>
  298.         public void Save(string valueName, object value) {
  299.             try {
  300.                 if (registryKeyWritable == null) {
  301.                     registryKeyWritable = Registry.CurrentUser.CreateSubKey(registryPath);
  302.                 }
  303.                 Type type = value.GetType();
  304.                 if (type == typeof(bool)) {
  305.                     registryKeyWritable.SetValue(valueName,
  306.                         (bool)value ? 1 : 0, RegistryValueKind.DWord);
  307.                 } else if (type == typeof(byte)) {
  308.                     registryKeyWritable.SetValue(valueName,
  309.                         (int)checked((byte)value), RegistryValueKind.DWord);
  310.                 } else if (type == typeof(char)) {
  311.                     registryKeyWritable.SetValue(valueName,
  312.                         (int)(char)value, RegistryValueKind.DWord);
  313.                 } else if (type == typeof(Color)) {
  314.                     registryKeyWritable.SetValue(valueName,
  315.                         ((Color)value).ToArgb(), RegistryValueKind.DWord);
  316.                 } else if (type == typeof(DateTime)) {
  317.                     registryKeyWritable.SetValue(valueName,
  318.                         ((DateTime)value).ToBinary(), RegistryValueKind.QWord);
  319.                 } else if (type == typeof(decimal)) {
  320.                     registryKeyWritable.SetValue(valueName,
  321.                         ((decimal)value).ToString(CultureInfo.InvariantCulture), RegistryValueKind.String);
  322.                 } else if (type == typeof(double)) {
  323.                     registryKeyWritable.SetValue(valueName,
  324.                         BitConverter.DoubleToInt64Bits((double)value), RegistryValueKind.QWord);
  325.                 } else if (type == typeof(float)) {
  326.                     registryKeyWritable.SetValue(valueName,
  327.                         BitConverter.ToInt32(BitConverter.GetBytes((float)value), 0), RegistryValueKind.DWord);
  328.                 } else if (type == typeof(int)) {
  329.                     registryKeyWritable.SetValue(valueName,
  330.                         (int)value, RegistryValueKind.DWord);
  331.                 } else if (type == typeof(long)) {
  332.                     registryKeyWritable.SetValue(valueName,
  333.                         (long)value, RegistryValueKind.QWord);
  334.                 } else if (type == typeof(sbyte)) {
  335.                     registryKeyWritable.SetValue(valueName,
  336.                         (int)(sbyte)value, RegistryValueKind.DWord);
  337.                 } else if (type == typeof(short)) {
  338.                     registryKeyWritable.SetValue(valueName,
  339.                         (int)(short)value, RegistryValueKind.DWord);
  340.                 } else if (type == typeof(TimeSpan)) {
  341.                     registryKeyWritable.SetValue(valueName,
  342.                         ((TimeSpan)value).Ticks, RegistryValueKind.QWord);
  343.                 } else if (type == typeof(uint)) {
  344.                     registryKeyWritable.SetValue(valueName,
  345.                         (int)checked((uint)value), RegistryValueKind.DWord);
  346.                 } else if (type == typeof(ulong)) {
  347.                     registryKeyWritable.SetValue(valueName,
  348.                         (long)checked((ulong)value), RegistryValueKind.QWord);
  349.                 } else if (type == typeof(ushort)) {
  350.                     registryKeyWritable.SetValue(valueName,
  351.                         (int)checked((ushort)value), RegistryValueKind.DWord);
  352.                 } else {
  353.                     registryKeyWritable.SetValue(valueName,
  354.                         value);
  355.                 }
  356.                 Saved?.Invoke(this, new PersistentSettingsEventArgs(registryKeyWritable));
  357.             } catch (IOException exception) {
  358.                 Debug.WriteLine(exception);
  359.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyWritable, exception));
  360.             } catch (SecurityException exception) {
  361.                 Debug.WriteLine(exception);
  362.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyWritable, exception));
  363.             } catch (UnauthorizedAccessException exception) {
  364.                 Debug.WriteLine(exception);
  365.                 Error?.Invoke(this, new PersistentSettingsEventArgs(registryKeyWritable, exception));
  366.             } catch (Exception exception) {
  367.                 Debug.WriteLine(exception);
  368.             }
  369.         }
  370.     }
  371.  
  372.     /// <summary>
  373.     /// Implements custom event args used by PersistentSettings class.
  374.     /// </summary>
  375.     public sealed class PersistentSettingsEventArgs : EventArgs {
  376.  
  377.         /// <summary>
  378.         /// The Exception property.
  379.         /// </summary>
  380.         public Exception Exception { get; private set; }
  381.  
  382.         /// <summary>
  383.         /// The RegistryKey property.
  384.         /// </summary>
  385.         public RegistryKey RegistryKey { get; private set; }
  386.  
  387.         /// <summary>
  388.         /// Initializes a new instance of the
  389.         /// <see cref="PersistWindowStateEventArgs"/> class.
  390.         /// </summary>
  391.         public PersistentSettingsEventArgs(RegistryKey registryKey, Exception exception = null) {
  392.             Exception = exception;
  393.             RegistryKey = registryKey;
  394.         }
  395.     }
  396. }
  397.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement