Winreg中QueryInfoKey返回注册表键最后修改时间错误问题排查
解决注册表键最后修改时间计算错误的问题
你遇到的错误日期问题根源很明确:你把Windows的文件时间格式当成了Unix时间戳来处理。
QueryInfoKey返回的第三个值确实是自1601年1月1日以来的100纳秒间隔数,而datetime.fromtimestamp()只认1970年1月1日起始的Unix时间戳,直接除以1e9把100纳秒转成秒,相当于把1601年的时间当成了1970年的,自然会算出离谱的日期。
修正方案
我们需要先转换Windows时间到Unix时间戳的基准:
- 计算1601-01-01到1970-01-01的秒数差:这个固定值是
11644473600秒 - 将100纳秒数转换为秒:除以
1e7(因为1秒 = 10^7个100纳秒) - 用转换后的秒数减去上面的时间差,得到正确的Unix时间戳,再转成datetime
修正并优化后的代码
我还优化了你的代码结构,用for循环代替while,加上自动关闭注册表键的逻辑(避免资源泄漏),同时缩小了权限范围(只读足够):
import winreg from datetime import datetime def get_reg_key_modify_times(subkeylist): # Windows时间起点(1601-01-01)到Unix时间起点(1970-01-01)的固定秒数差 WINDOWS_UNIX_EPOCH_DIFF = 11644473600 for keypath in subkeylist: try: # 使用with语句自动关闭注册表键,避免资源泄漏 with winreg.OpenKey(winreg.HKEY_CURRENT_USER, keypath, 0, winreg.KEY_READ) as key: # 获取100纳秒为单位的最后修改时间 hundred_nanos = winreg.QueryInfoKey(key)[2] # 转换为Unix时间戳(秒) unix_ts = (hundred_nanos / 1e7) - WINDOWS_UNIX_EPOCH_DIFF # 转换为datetime并格式化 modify_time = datetime.fromtimestamp(unix_ts) formatted_time = modify_time.strftime('%Y-%m-%dT%H:%M:%S.%f') print(f"键 {keypath} 的最后修改时间:{formatted_time}") except WindowsError as e: print(f"处理键 {keypath} 时出错:{str(e)}")
关键细节说明
- 权限:原来用
KEY_ALL_ACCESS没必要,KEY_READ足够读取键信息,更安全 - 资源管理:
with语句会自动调用CloseKey(),避免忘记关闭注册表键导致的资源泄漏 - 错误处理:捕获异常时输出具体键路径和错误信息,方便排查哪个键无法访问
这样运行后就能得到正确的最后修改时间了。
内容的提问来源于stack exchange,提问作者Mr.Pixel
相关产品推荐
相关产品推荐

