You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Winreg中QueryInfoKey返回注册表键最后修改时间错误问题排查

解决注册表键最后修改时间计算错误的问题

你遇到的错误日期问题根源很明确:你把Windows的文件时间格式当成了Unix时间戳来处理。

QueryInfoKey返回的第三个值确实是自1601年1月1日以来的100纳秒间隔数,而datetime.fromtimestamp()只认1970年1月1日起始的Unix时间戳,直接除以1e9把100纳秒转成秒,相当于把1601年的时间当成了1970年的,自然会算出离谱的日期。

修正方案

我们需要先转换Windows时间到Unix时间戳的基准:

  1. 计算1601-01-01到1970-01-01的秒数差:这个固定值是11644473600秒
  2. 将100纳秒数转换为秒:除以1e7(因为1秒 = 10^7个100纳秒)
  3. 用转换后的秒数减去上面的时间差,得到正确的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:43:42