指定的强制转换无效 - 对象为长

时间:2017-10-23 18:29:24

标签: c# registry

我正在研究一些将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返回的对象。

1 个答案:

答案 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.ParseDateTime.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);