我正在研究一些将DateTime值写入Windows注册表然后检索它的代码。
代码
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"));
最后一行抛出以下异常:
Specified cast is not valid
FromBinary方法需要一个long
参数,所以我试图转换从GetValue返回的对象。
答案 0 :(得分:4)
使用SubKey.SetValue(string, object)时,除非是32位整数,否则该值将存储为字符串。来自documentation:
此方法重载将除32位整数以外的数字类型存储为字符串。枚举元素存储为包含元素名称的字符串。
这是一个问题,因为DateTime.ToBinary
产生一个64位整数。因此它将转换为字符串进行存储。当您检索值cast
而不是Convert
时,它会失败。
如果要将日期存储为二进制数,可以使用the overload of SetValue that lets you specify the type来解决此问题。例如:
subKey.SetValue(trialEndDate, dt.ToBinary(), RegistryValueKind.QWord);
这会将二进制值存储为64位整数,并允许您将其作为相同的值进行检索。
您还可以选择将DateTime存储为字符串(对于编辑注册表的人来说可能更具可读性)并使用DateTime.Parse
或DateTime.ParseExact
对其进行解析。这可能是我会这样做的:
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);