I have a function that loops through a list containing found registry key paths. I now need to find the date each registry key was last changed from that list of keys.
def get_values(subkeylist):
try:
x = 0
nanos = []
while x < len(subkeylist):
keypath = subkeylist[x]
key = OpenKey(HKEY_CURRENT_USER, keypath, 0, KEY_ALL_ACCESS)
secs = QueryInfoKey(key)[2] / 1e9
dt = datetime.fromtimestamp(secs)
dt.strftime('%Y-%m-%dT%H:%M:%S.%f')
print(dt)
x += 1
except WindowsError:
pass
I feel like I have either done something wrong here, or the value being held in the key is incorrect. The output in the shell is as follows:
1974-03-04 05:54:37.481353 1974-03-04 05:54:37.481433 1974-03-04 05:54:37.481443
And here is the actual output before conversion in nanoseconds since EPOCH 1601.(QueryInfoKey: An integer giving when the key was last modified (if available) as 100’s of nanoseconds since Jan 1, 1601).
131608477481353446 131608477481433451 131608477481443451
As you pointed out, the registry seems to store timestamps in the FILETIME
structure format, whereas Python's date and time functions expect Unix timestamps, i.e. the number of seconds since 1 Jan 1970.
If you plug 01.01.1601 + (131608477481353446 * 100 ns)
into WolframAlpha, you will see that it translates to 19 Jan 2018, so the value in the key seems to be right, you just need to decode it properly.
from datetime import datetime, timedelta
WIN32_EPOCH = datetime(1601, 1, 1)
def dt_from_win32_ts(timestamp):
return WIN32_EPOCH + timedelta(microseconds=timestamp // 10)
key = OpenKey(...)
ts = QueryInfoKey(key)[2]
dt = dt_from_win32_ts(ts)
print(dt.strftime('%Y-%m-%dT%H:%M:%S.%f'))
# 2018-01-19T15:02:28.135344
Python's datetime
module supports microsecond resolution, which means we lose one decimal place of precision.