yeasir007

Monday, October 22, 2018

How to read/write windows registry in wpf based application

Read/Write Windows Registry:




In the modern application sometimes it’s essential to use Windows registry for storing application settings to meet all requirements, which is a hierarchical database of windows system. It’s a logical repository that is able to store user-specific settings. It’s a tree-based architecture having two basic elements, key & values. The values can be string, binary, or DWORD depending on the constraint. The category of Microsoft Windows system are as follows:


    Ã¨  CurrentUser. Stores information about user preferences.

    Ã¨  LocalMachine. Stores configuration information for the local machine.

    Ã¨  ClassesRoot. Stores information about types (and classes) and their properties.

    Ã¨  Users. Stores information about the default user configuration.

    Ã¨  PerformanceData. Stores performance information for software components.

    Ã¨  CurrentConfig. Stores non-user-specific hardware information.

    Ã¨  DynData. Stores dynamic data.




The Registry class has a static field corresponding to each of these key types. The Registry class members are described as follows:

    Ã¨  ClassesRoot. Returns a RegistryKey type that provides access to the HKEY_CLASSES_ROOT key.

    Ã¨  CurrentConfig. Returns a RegistryKey type that provides access to the HKEY_CURRENT_CONFIG key.

    Ã¨  CurrentUser. Returns a RegistryKey type that provides access to the HKEY_CURRENT_USER key.

    Ã¨  DynData. Returns a RegistryKey type that provides access to the HKEY_DYN_DATA key.

    Ã¨  LocalMachine. Returns a RegistryKey type that provides access to the HKEY_LOCAL_MACHINE key.

    Ã¨  PerformanceData. Returns a RegistryKey type that provides access to the HKEY_PERFORMANCE_DATA key.

    Ã¨  Users. Returns a RegistryKey type that provides access to the HKEY_USERS key.


      

      In  this post, we will work with HKEY_LOCAL_MACHINE & HKEY_CURRENT_USER

      Before writing code, we can get a basic idea regarding the API list of the Microsoft registry class. For more details, you can browse Microsoft API documentation for Registry Class.


    Ã¨  SubKeyCount: The number of keys under the current key.

    Ã¨  ValueCount: The number of keys under the current key.

    Ã¨  Close(): Close the key

    Ã¨  CreateSubKey() : Creates a new subKey if one does not exist. Otherwise opens an existing subKey.

    Ã¨  DeleteSubKey(): Deletes the subKey passed by this API.

    Ã¨  DeleteSubKeyTree() : Deletes the entire subKey passed by this API.

    Ã¨  DeleteValue() : Deletes the value specified from the current key.

    Ã¨  GetSubKeyNames() : Returns an array of names of all the subKey.

    Ã¨  GetValue() : Gets the value specified by the value name passed. Returns null or assigned default value if does not exist.

    Ã¨  GetValueNames() : Retrieves an array of names of all the values.

    Ã¨  OpenSubKey() : Opens a subKey specified by the string passed.

    Ã¨  SetValue() : Sets a value in the registry with the value passed into the second parameter, The first one is the key name.

 



Actually, GetValue may return String, bool & DWORD based on the requirement, So we will implement a generic type method for both GetValue & SetValue which will handle all of the types.

using Microsoft.Win32;
using MyGitHubProject.Enums;
using System;
using DWORD = System.Int32;

namespace MyGitHubProject.RegistryUtil
{
  public class RegistryManager
  {
    #region Variables
    const string USER_ROOT_HKCU = "HKEY_CURRENT_USER";
    const string USER_ROOT_HKLM = "HKEY_LOCAL_MACHINE";
    #endregion
    public RegistryManager()
    { 

    }
    ~RegistryManager()
    {

    }

    public static DWORD GetValue(string subkey, string registryItem)
    {
        string keyName = USER_ROOT_HKCU + "\\" + subkey;
        return (DWORD)Registry.GetValue(keyName, registryItem, -1);
    }

    // <typeparam name="T">Generic type. String/bool/int etc</typeparam>
    public static T GetValue<T>(string subkey, string registryItem, RegistryValueKind registryValueKind)
    {
        T retrunVal = default(T);
        try
        {
            string keyName = USER_ROOT_HKCU + "\\" + subkey;
            retrunVal = (T)Registry.GetValue(keyName, registryItem, null);//String.Emptyty
        }
        catch (Exception ex)
        {
            return default(T);
        }

        return retrunVal;
    }


    // <typeparam name="T">Generic type. String/bool/int etc</typeparam>
    // <param name="registryHive">Type of registry space HKLM or HKCU</param>
    public static T GetValue<T>(string subkey, string registryItem, RegistryHive registryHive)
    {
        string keyName = String.Empty;

        T retrunVal = default(T);

        try
        {
            if (registryHive == RegistryHive.LocalMachine)
            {
                keyName = USER_ROOT_HKLM + "\\" + subkey;
            }
            else
            {
                keyName = USER_ROOT_HKCU + "\\" + subkey;
            }

            retrunVal = (T)Registry.GetValue(keyName, registryItem, null);//String.Empty
        }
        catch (Exception ex)
        {
            retrunVal = default(T);
        }

        return retrunVal;
    }

    // <typeparam name="T">Generic type. String/bool/int etc</typeparam>
    /// <param name="valueKind">Registry value type.</param>
    public static DWORD SetValue<T>(string subkey, string registryItem, T registryValue, RegistryValueKind valueKind = RegistryValueKind.DWord)
    {
        string keyName = USER_ROOT_HKCU + "\\" + subkey;

        try
        {
            Registry.SetValue(keyName, registryItem, registryValue, valueKind);
            return 1;
        }
        catch (Exception ex)
        {
        }

        return 0;
    }

    public static void CreateKey(string key)
    {
        try
        {
            Registry.CurrentUser.CreateSubKey(key);
        }
        catch (Exception ex)
        {
        }
    }

    // <param name="rkey">Registry.CurrentUser/Registry.LocalMachine</param>
    public static void DeleteValue(string subkey, string registryItem, RegistryKey rkey)
    {
        string keyName = USER_ROOT_HKCU + "\\" + subkey;
        try
        {
            using (RegistryKey key = rkey.OpenSubKey(keyName, true))
            {
                if (key != null)
                {
                    key.DeleteValue(registryItem);
                }
            }
        }
        catch (Exception ex)
        {
        }
     }
   }
 }



Here bellow is the calling procedure of generic type function:


using Microsoft.Win32;
using System;
using System.Globalization;
using System.Threading;
using DWORD = System.Int32;
namespace MyGitHubProject.RegistryUtil
{
  public class RegistryUtils
  {
    #region Registry Paths
    const string RegPathDefault = "Software\\MyGitHubProject\\UseRegistryInWPF";
    #endregion

    #region Registry Keys
    const string RegKeyInstallPath = "InstallPath";
    const string RegKeyIsLanguageRTL = "IsLanguageRTL";
    #endregion

    public RegistryUtils()
    {

    }
    ~RegistryUtils()
    {

    }

    #region Method Implementation

    public static void CreateSettingRegistryKey()
    {
        RegistryManager.CreateKey(RegPathDefault);
    }

    public static void SetInstallPath(string installPath)
    {
        RegistryManager.SetValue<string>(RegPathDefault, RegKeyInstallPath, installPath, RegistryValueKind.String);
    }

    public static string GetInstallPath(string installPath)
    {
         return RegistryManager.GetValue<string>(RegPathDefault, RegKeyInstallPath,RegistryValueKind.String);
    }       

    public static void SetSupportRTL(DWORD value)
    {
        RegistryManager.SetValue(RegPathDefault, RegKeyIsLanguageRTL, value, RegistryValueKind.DWord);
    }

    public static DWORD GetSupportRTL(DWORD value)
    {
        return RegistryManager.GetValue<DWORD>(RegPathDefault, RegKeyIsLanguageRTL, value, RegistryValueKind.DWord);
    }

    public static DWORD GetSupportRTLEx(DWORD value)
    {
        return RegistryManager.GetValue(RegPathDefault, RegKeyIsLanguageRTL);
    }

    public static bool Is64bitOS()
    {
        return Environment.Is64BitOperatingSystem;
    }

    #endregion
  }
}




N.B : Please make ensure to call CreateSettingRegistryKey() before calling SetValue() API.



Happy coding. :)

No comments:

Post a Comment

Thanks for your comments