我正在使用WinAPI在Windows XP SP3框上设置时区。我正在从HKLM\Software\Microsoft\WindowsNT\Time Zones\<time zone name>
键读取时区信息,然后将时区设置为指定的时区。
我枚举时区键下的键,抓取TZI
值并将其填入TIME_ZONE_INFORMATION
结构中以传递给SetTimeZoneInformation。一切似乎都在第一关。时区更改,不会返回错误。
第二次执行此操作(同一用户,新会话,在userinit之前登录时),呼叫成功,但系统未反映时区更改。文件上的时钟和时间戳都不会更新到新时区。当我导航到:
HKLM\System\CurrentControlSet\Control\TimeZoneInformation
我的新时区信息已存在。
当我设定时区时,会发生一些奇怪的事情:
TIME_ZONE_INFORMATION
结构中时,我注意到结构的DaylightDate.wDay
和StandardDate.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 错误(指定的权限 不存在。 )。
答案 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
。执行这些步骤后,时区将按预期更改。