更改系统时区成功一次,然后不再更改

时间:2010-03-31 16:53:52

标签: c++ winapi timezone

我正在使用WinAPI在Windows XP SP3框上设置时区。我正在从HKLM\Software\Microsoft\WindowsNT\Time Zones\<time zone name>键读取时区信息,然后将时区设置为指定的时区。

我枚举时区键下的键,抓取TZI值并将其填入TIME_ZONE_INFORMATION结构中以传递给SetTimeZoneInformation。一切似乎都在第一关。时区更改,不会返回错误。

第二次执行此操作(同一用户,新会话,在userinit之前登录时),呼叫成功,但系统未反映时区更改。文件上的时钟和时间戳都不会更新到新时区。当我导航到: HKLM\System\CurrentControlSet\Control\TimeZoneInformation我的新时区信息已存在。

当我设定时区时,会发生一些奇怪的事情:

  • 当我从注册表中解析TZI二进制值以存储在我的TIME_ZONE_INFORMATION结构中时,我注意到结构的DaylightDate.wDayStandardDate.wDay字段始终设置为0
  • 我在拨打SetTimeZoneInformation后尝试立即拨打GetTimeZoneInformation但是呼叫失败并出现1300错误(并非所有引用的权限或组都分配给了呼叫者。)

我也确保发送WM_BROADCAST消息,以便资源管理器了解最新情况。

认为是将字节数组解析为TIME_ZONE_INFORMATION结构?或者我错过了一些重要的事情?

编辑:

找到一份文件,说明发生这种情况的原因:here。特权在Vista中引入...感谢MSDN文档...

  

根据Microsoft documentation   我正在启用SE_TIME_ZONE_NAME   当前流程的特权
  令牌。但是当我试图打电话时   LookupPriviledgeValue代表   SE_TIME_ZONE_NAME我得到1313   错误(指定的权限   不存在。 )。

2 个答案:

答案 0 :(得分:1)

尝试使用LsaAddAccountRights而不是LookupPrivilegeValue和AdjustTokenPrivileges来设置SE_TIME_ZONE_NAME。另请参阅this topic

答案 1 :(得分:0)

在搞砸了一段时间之后我已经解决了这个问题,但我不确定是什么步骤修复了它。我添加了一个额外的子句来检查操作系统,以验证是否调整进程令牌以启用SE_TIME_ZONE_NAME。它现在只在XP后的操作系统上执行此操作。

我还改变了TZI注册表值如何存储到我的结构中。我意识到在TIME_ZONE_INFORMATION MSDN文档中包含了用于注册表verison(REG_TZI_FORMAT)的结构。简单地将二进制值直接读入结构消除了一些代码。

我还保证填充了BOTH DaylightName和StandardName。

最后,我在RegFlushKey(HKEY_LOCAL_MACHINE)电话后立即拨打了SetTimeZoneInformation。执行这些步骤后,时区将按预期更改。