HKLM \ SYSTEM \ CurrentControlSet \ Control \ TimeZoneInformation \ TimeZoneKeyName损坏?

我正在尝试确定Windows系统的当前时区。 下面的代码片段(松散地)基于@MattJohnson在这个线程上的答案: 当OS显示语言是非英文的时候获取本地的时区标识符

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); } } } 

如果我在第一行放置一个断点“if(string.IsNullOrEmpty(windowsTimeZoneId))”,那么这就是我在Visual Studiodebugging器中看到的:

在这里输入图像说明

这里发生了什么? RegistryKey.GetValue()正在返回一个装箱的string,但它为什么不检测两个hex00字节并在那里终止string?

到目前为止,我已经在我的两台电脑上testing过了。 这是从Windows 7 64位运行的。 另一个,运行Windows 7 32位,除了它说,返回的string的长度是128个字符而不是127。

使用regedit.exe查看registry项时,看起来很好,只显示“Romance Standard Time”。

有点谷歌search出现这个问题https://social.msdn.microsoft.com/Forums/sqlserver/en-US/eca7ad76-c910-46be-8fb9-876c7cde5c69/registry-read-time-zone-info-differ-当代码build立40框架在主机系统赢得7-64位?论坛= csharpgeneral否则我找不到任何东西。

该程序正在使用Visual Studio 2012构build,并针对.Net 2.0。

正如你所看到的,我已经添加了代码来考虑这个“腐败”的结果,但是如果有人能够向我解释这里发生的事情,甚至可以避免整个问题,我还是会很感激。

编辑:

该程序正在使用Visual Studio 2012构build,并针对.Net 2.0。

嗯,情节变厚了。 那个陈述并不完全正确。 上面显示的代码残块是在一个库目录.Net 2.0中构build的,但是它是从一个针对.Net 4.0的程序调用的。 现在我已经尝试从一个以.Net 2.0为目标的程序调用它,并且没有任何问题,RegistryKey.GetValue()只是返回“Romance Standard Time”。 因此,它似乎与.Net Framework 4.0有关,正如MSDN上的发布所暗示的那样。

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

这是有点偏离主题,但我会很感激,如果有人会看看我在Superuser.com相关的张贴,因为我没有得到即时满足,我想要得到这个解决,所以我知道我是否应该仍然恐慌。 谢谢。

https://superuser.com/questions/859031/possible-malware-modification-of-windows-registry-entry

在注册表中设置字符串或多字符串值时,Windows不检查语义; 它只是存储提供的二进制内容,以程序员指定的长度。 这意味着一个字符串可能过早地以null结尾,或者相反,根本不是null结尾的。 (顺便提一下,这确实有安全隐患:尽管我不认为过早的空终止可能会带来风险,但是本地代码无法处理字符串不以空终止的情况。

根据汉斯(在他的删除答案)4.x以前版本的.NET会忽略额外的数据,如果字符串过早空终止,而4.x包括它。 所以这就是为什么你一开始使用4.x就只注意到这个问题的原因。

至于为什么这个特定的价值是过早的空终止,这似乎是微软的粗心。 如果删除多余的数据,然后更改时区,则会再次出现额外的数据。 所以这似乎是Windows本身就是这样做的。 数据看起来是随机的,所以我不相信这是故意的。 事实上,这在技术上可能构成数据泄露漏洞,尽管可能没有实际影响。

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

(如果我有时间,下周回去工作时,我会在虚拟机上安装一个干净的Windows副本,并确认问题是否存在,绝对没有第三方软件存在。如果是,我会考虑报告它 – 我怀疑MS会发布一个补丁,但它可能会在未来版本的Windows中得到修复。)