I'm working on some code that writes a DateTime value to the Windows registry and then retrieves it.
Code
RegistryKey subKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\" + Project.Properties.Resources.PRODUCT_NAME, true);
DateTime dt = DateTime.Now;
subKey.SetValue("TrialEndDate", dt.ToBinary());
DateTime dt2 = DateTime.FromBinary((long)subKey.GetValue("TrialEndDate"));
The last line throws the following exception:
Specified cast is not valid
The FromBinary method expects a long
parameter so I'm attempting to cast the object returned from GetValue.
When you use SubKey.SetValue(string, object), the value is stored as a string unless it is a 32-bit integer. From the documentation:
Numeric types other than 32-bit integers are stored as strings by this method overload. Enumeration elements are stored as strings containing the element names.
This present a problem, because DateTime.ToBinary
produces a 64-bit integer. So it will be converted to a string for storage. When you retrieve the value you are cast
ing instead of Convert
ing, so it'll fail.
If you want to store the date as a binary number, you can fix this by using the overload of SetValue that lets you specify the type. For example:
subKey.SetValue(trialEndDate, dt.ToBinary(), RegistryValueKind.QWord);
This will store the binary value as a 64-bit integer and allow you to retrieve it as the same.
You could also choose to store the DateTime as a string (which might be more readable to someone editing the registry) and parse it using DateTime.Parse
or DateTime.ParseExact
. This is probably how I would do it:
const string FORMAT = ""yyyyMMddHHmmss";
RegistryKey subKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\" + Project.Properties.Resources.PRODUCT_NAME, true);
var dt = DateTime.Now;
subKey.SetValue("TrialEndDate", dt.String(FORMAT), RegistryValueKind.String);
var storedValue = subKey.GetValue("TrialEndDate") as string;
var dt2 = DateTime.ParseExact(storedValue, FORMAT);