Introduction
When I migrated to .NET from Borland Delphi, I felt a lack in the standard RegistryKey
class. There are methods like WriteCurrency
, WriteDate
, and WriteBinaryData
in Delphi's TRegistry
class. Some useful methods working with the RegistryValueKind
enumeration were added in .NET 2.0. But there is still a problem: how, for example, to save a value of the System.Decimal
type in a registry key. The TypedRegistry assembly contains a class which allows to write and read data of the following types to/from a registry key: String
, Byte[]
, Int32
, Boolean
, DateTime
, Decimal
, Double
, Guid
, Int64
.
Though this is possible with .NET 2.0, the values are never saved using the REG_QWORD
format (introduced in Windows 2000) because .NET 1.1 has no support for such a format. The TypedRegistry assembly was aimed for both .NET versions (1.1 and 2.0). So, all 8-byte values of the DateTime
, Double
, and Int64
types are saved as byte arrays.
AcedRegistry Class
public class AcedRegistry : IDisposable
Provides methods for writing/reading typed data to/from the registry.
public AcedRegistry(AcedRootKey registryRootKey, string registryKey, bool writable)
Opens a root registry key (such as HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE) specified by the registryRootKey
parameter. Then, opens a key passed as string via the registryKey
parameter. If the value of the writable
parameter is false
, the registry key is opened in read-only mode. If that value is true
, the registry key is opened (or created, if not exists) in read-write mode.
For example, you may pass the AcedRootKey.LocalMachine
value in the first parameter, and the @"Software\CompanyName\ApplicationName" string in the registryKey
parameter. The following is the list of possible values for the registryRootKey
parameter. Each value corresponds to an instance of the root key exposed by the Microsoft.Win32.Registry
class:
AcedRootKey.ClassesRoot
AcedRootKey.CurrentConfig
AcedRootKey.CurrentUser
AcedRootKey.DynData
AcedRootKey.LocalMachine
AcedRootKey.PerformanceData
AcedRootKey.Users
public Microsoft.Win32.RegistryKey RegistryKey { get; }
Gets the related instance of the Microsoft.Win32.RegistryKey
class. This property returns null
if there is an error during opening or creating a registry key in the constructor of this class.
public void Dispose()
Closes the related registry key, and flushes it to disk if its contents have been modified.
public void Put(string valueName, String value)
public void Put(string valueName, Byte[] value)
public void Put(string valueName, Int32 value)
public void Put(string valueName, Boolean value)
public void Put(string valueName, DateTime value)
public void Put(string valueName, Decimal value)
public void Put(string valueName, Double value)
public void Put(string valueName, Guid value)
public void Put(string valueName, Int64 value)
Writes the value
to the open registry key, with the value name specified by the first parameter (valueName
).
public bool Get(string valueName, ref String value)
public bool Get(string valueName, ref Byte[] value)
public bool Get(string valueName, ref Int32 value)
public bool Get(string valueName, ref Boolean value)
public bool Get(string valueName, ref DateTime value)
public bool Get(string valueName, ref Decimal value)
public bool Get(string valueName, ref Double value)
public bool Get(string valueName, ref Guid value)
public bool Get(string valueName, ref Int64 value)
Reads a value of the corresponding type with the specified name (valueName
) from the open registry key. It is then returned in the value
parameter. The method returns true
if the value was successfully read. If there is no value with such a name in the current registry key, the method returns false
, and does not modify the value
parameter.
public String GetDef(string valueName, String defaultValue)
public Byte[] GetDef(string valueName, Byte[] defaultValue)
public Int32 GetDef(string valueName, Int32 defaultValue)
public Boolean GetDef(string valueName, Boolean defaultValue)
public DateTime GetDef(string valueName, DateTime defaultValue)
public Decimal GetDef(string valueName, Decimal defaultValue)
public Double GetDef(string valueName, Double defaultValue)
public Guid GetDef(string valueName, Guid defaultValue)
public Int64 GetDef(string valueName, Int64 defaultValue)
Reads a value of the corresponding type with the specified name (valueName
) from the open registry key, and returns that value as the method's result. If there is no value with such a name in the related registry key, the method returns a value of the defaultValue
parameter.
Example of Usage
The following is a code fragment which saves and loads the program configuration as a set of values in the registry key:
private const string
DemoRegistryKeyName = "Software\\TypedRegistryDemo",
cfgStringValueName = "StringValue",
cfgDateTimeValueName = "DateTimeValue",
cfgDecimalValueName = "DecimalValue",
cfgBooleanValueName = "BooleanValue",
cfgEnumValueName = "EnumerationElement",
cfgByteArrayValueName = "Image";
private static string _stringValue;
private static DateTime _dateTimeValue;
private static decimal _decimalValue;
private static bool _booleanValue;
private static MyColors _enumValue;
private static byte[] _byteArrayValue;
private static void SaveConfig()
{
using (AcedRegistry config =
new AcedRegistry(AcedRootKey.CurrentUser,
DemoRegistryKeyName, true))
{
config.Put(cfgStringValueName, _stringValue);
config.Put(cfgDateTimeValueName, _dateTimeValue);
config.Put(cfgDecimalValueName, _decimalValue);
config.Put(cfgBooleanValueName, _booleanValue);
config.Put(cfgEnumValueName, (int)_enumValue);
config.Put(cfgByteArrayValueName, _byteArrayValue);
}
}
private static void LoadConfig()
{
using (AcedRegistry config = new AcedRegistry(AcedRootKey.CurrentUser,
DemoRegistryKeyName, false))
{
config.Get(cfgStringValueName, ref _stringValue);
config.Get(cfgDateTimeValueName, ref _dateTimeValue);
config.Get(cfgDecimalValueName, ref _decimalValue);
config.Get(cfgBooleanValueName, ref _booleanValue);
_enumValue = (MyColors)config.GetDef(cfgEnumValueName, (int)_enumValue);
config.Get(cfgByteArrayValueName, ref _byteArrayValue);
}
}
It is convenient to enclose all method calls which access the registry into the using
statement. Thus, we can be sure that the instance of the AcedRegistry
class will be disposed at the end and the related instance of the standard RegistryKey
class will be closed.
We can even save a value of a custom enumeration type in the registry as a value of the System.Int32
(or maybe System.Int64
) type. In the above code fragment, we cast a value of the MyColors
enumeration type to int
before passing it to the Put
method. Then, we cast it back to the MyColors
type when the value is returned from the GetDef
method.
Conclusion
The described class contains several methods to work with registry data in a typed manner. This is just an add-on over the standard RegistryKey
class. To access the related RegistryKey
while working with this class, please use the property of the same name.