.net HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName是否损坏?

.net HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName是否损坏?,.net,windows,timezone,registry,.net,Windows,Timezone,Registry,我正在尝试确定Windows系统的当前时区。以下代码片段(松散地)基于@MattJohnson对此线程的回答: 如果我在第一行“If(string.IsNullOrEmpty(windowsTimeZoneId))”上放置断点,则我在Visual Studio调试器中看到的是: 这是怎么回事?RegistryKey.GetValue()返回一个装箱字符串,但为什么它不检测两个十六进制00字节并在那里终止该字符串 到目前为止,我已经在我的两台电脑上进行了测试。这是一台运行64位Windows 7

我正在尝试确定Windows系统的当前时区。以下代码片段(松散地)基于@MattJohnson对此线程的回答:

如果我在第一行“If(string.IsNullOrEmpty(windowsTimeZoneId))”上放置断点,则我在Visual Studio调试器中看到的是:

这是怎么回事?RegistryKey.GetValue()返回一个装箱字符串,但为什么它不检测两个十六进制00字节并在那里终止该字符串

到目前为止,我已经在我的两台电脑上进行了测试。这是一台运行64位Windows 7的电脑。另一个运行32位Windows7,除了它说返回字符串的长度是128个字符而不是127个字符外,其他都是相同的

使用regedit.exe查看注册表项时,它看起来很好,只显示“标准时间”

谷歌搜索了一下这个问题,否则我什么都找不到

该程序是使用Visual Studio 2012构建的,目标是.Net 2.0

正如您所看到的,我添加了代码来考虑这个“腐败”的结果,但是如果有人能向我解释这里发生了什么,甚至如何避免整个问题,我还是很感激的

编辑:

该程序是使用Visual Studio 2012构建的,目标是.Net 2.0

嗯,情节变得复杂了。这种说法并不完全正确。上面显示的代码残端位于为.NET2.0构建的库程序集中,但它是从针对.NET4.0的程序调用的。现在我试着从一个以.NET2.0为目标的程序中调用它,没有问题,RegistryKey.GetValue()只返回“标准时间”。因此,它似乎确实与.NETFramework4.0有关,正如MSDN上的帖子所暗示的那样

编辑2-开始认为这是“正常的”

这是一个有点离题的话题,但如果有人能看看我在Superuser.com上的相关帖子,我会很感激,因为我在那里没有得到即时的满足,我想解决这个问题,这样我就知道我是否还应该感到恐慌。谢谢


当在注册表中设置字符串或多字符串值时,Windows不会检查语义;它只存储提供的任何二进制内容,长度由程序员指定。这意味着字符串可以过早地以null结尾,或者相反,根本不以null结尾。(顺便说一句,这确实会带来安全隐患:虽然我不认为过早终止null很可能会带来风险,但如果本机代码无法处理字符串未以null结尾的情况,则可能会导致风险。)

根据Hans(在他删除的答案中)的说法,如果字符串过早地以null结尾,那么4.x之前的.NET版本将忽略额外的数据,而4.x包含它。这就是为什么在开始使用4.x时,您才注意到这个问题

至于为什么这个特定的值过早地以null结尾,这似乎是微软的疏忽。如果删除额外数据,然后更改时区,则会重新显示额外数据。因此,似乎是Windows本身在这样做。这些数据在我看来是随机的,所以我不认为这是故意的。事实上,这在技术上可能构成数据暴露漏洞,尽管可能没有实际影响

我建议您搜索null,必要时截断字符串。有些情况下可能没有,例如,条目已被第三方代码修改,或者MS最终发布更新并修复了问题,或者,当然,如果您运行的是.NET 2.x。所以你需要处理这两种情况


(如果我有时间,当我下周回去工作的时候,我会在一个虚拟机上安装一个干净的Windows副本,并确认这个问题是绝对没有第三方软件存在的。如果是这样的话,我会考虑报告它——我怀疑MS会发布补丁,但是它可能会在Windows的未来版本中得到修复。)< /P>非常有趣的细节。还要注意,浪漫标准时间适用于欧洲,而不是墨西哥。所以这不是故意的,因为同一个字符串中的值是不相关的。@Matt:我怀疑多余的数据是随机的,就像分配缓冲区时内存中发生的任何事情一样。看起来Windows本身正在这样做;如果我删除多余的内容,然后更改时区,它会重新出现。每次看起来都是相同的数据,但我没有尝试重新启动机器,看看这是否会使它看起来有所不同。非常感谢您检查此信息,并感谢您的良好解释。现在我又可以安心睡觉了。(汉斯的回答让我非常不安,我正要联系一位新客户,并警告他们我可能在不经意间用一种无法检测的病毒感染了他们大约300台电脑。这会让我很受他们欢迎。)

    using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(
                                   @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"))
    {
       if (registryKey != null)
       {
          string windowsTimeZoneId = registryKey.GetValue("TimeZoneKeyName") as string;
          if (string.IsNullOrEmpty(windowsTimeZoneId))
             windowsTimeZoneId = registryKey.GetValue("StandardName") as string;
          if (!string.IsNullOrEmpty(windowsTimeZoneId))
          {
             int i = windowsTimeZoneId.IndexOf('\0');
             if (i != -1)
                windowsTimeZoneId = windowsTimeZoneId.Remove(i);
             return ConvertFromWindowsId(windowsTimeZoneId);
          }
       }
    }