【问题标题】:Changing the system time zone succeeds once and then no longer changes更改系统时区一次成功,然后不再更改
【发布时间】:2010-03-31 16:53:52
【问题描述】:

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

我枚举 Time Zones 键下的键,获取 TZI 值并将其填充到 TIME_ZONE_INFORMATION 结构中以传递给 SetTimeZoneInformation。一切似乎都在第一次通过。时区改变,不返回错误。

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

在设置时区时发生了一些奇怪的事情:

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

我还要确保发送 WM_BROADCAST 消息,以便 Explorer 知道发生了什么。

认为这是将字节数组解析为TIME_ZONE_INFORMATION 结构吗?还是我错过了其他重要的事情?

编辑:

找到一份说明为什么会发生这种情况的文档:here。特权是在 Vista 中引入的...感谢 MSDN 文档...

根据微软documentation 我正在启用 SE_TIME_ZONE_NAME 当前进程的权限
令牌。但是,当我尝试拨打
LookupPriviledgeValue for
SE_TIME_ZONE_NAME 时,我得到一个 1313 错误(指定的权限不会 不存在。 )。

【问题讨论】:

    标签: c++ winapi timezone


    【解决方案1】:

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

    【讨论】:

    • 感谢您的想法,但我认为 AdjustTokenPriviledge 工作正常。我编辑了问题,因为 SE_TIME_ZONE_NAME 在 XP 中不存在。
    【解决方案2】:

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

    我还更改了将 TZI 注册表值存储到我的结构中的方式。我意识到TIME_ZONE_INFORMATION MSDN 文档中包含用于注册表版本(REG_TZI_FORMAT)的结构。只需将二进制值直接读取到结构中即可消除一些代码。

    我还保证 DaylightName 和 StandardName 都已填充。

    最后我在SetTimeZoneInformation 通话后立即拨打了RegFlushKey(HKEY_LOCAL_MACHINE)。采取这些步骤后,时区将按预期发生变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 2013-08-30
      相关资源
      最近更新 更多