The first problem with discussing file last-access time is agreeing what you mean by a file’s last-access time.
The file system folks have one definition of the file last-access time,
namely the time the file was most recently opened and either read from
or written to.
This is the value retrieved by functions like
GetFileAttributesEx
,
GetFileTime
,
and FindFirstFile
.
The problem with this definition is that it doesn’t match the intuitive definition of last-access time, which is “the last time I accessed the file,” emphasis on the I. In fact, the intuitive definition of access is more specific: It’s “the last time I opened, modified, printed, or otherwise performed some sort of purposeful action on the file.”
This discrepancy between the file system definition and the intuitive definition means that a lot of operations trigger a file system access but shouldn’t count as an access from the user interface point of view. Here are some examples:
- Accessing the file to generate a preview or thumbnail image.
- Accessing the file to show its property sheet.
- Accessing the file to retrieve its icon.
- Accessing the file to retrieve properties to show in Explorer or some other viewer.
- Accessing the file in order to back it up.
- Accessing the file in order to display its context menu, something you aren’t supposed to be doing in the first place but people do it anyway.
Whenever some shell extension violates this rule, the shell team gets a bug report from some customer saying, “The last-access time shown in Explorer is wrong. A document which hasn’t been accessed in months shows a last-access time of today. After closer investigation, we found that the last-access time updates whenever we insert seemingly-innocuous operation here.”
If you’re writing a program which needs
to access the file contents but you not want to update
the last-access time, you can use the SetFileTime
function
with the special value 0xFFFFFFFF
in both members
of the FILETIME
structure passed
as the last-access time.
This magic value means “do not change the last-access time
even though I’m accessing the file.”
BOOL DoNotUpdateLastAccessTime(HANDLE hFile) { static const FILETIME ftLeaveUnchanged = { 0xFFFFFFFF, 0xFFFFFFFF }; return SetFileTime(hFile, NULL, &ftLeaveUnchanged, NULL); }
As the documentation notes, you have to call this function immediately after opening the file.
Going back to that linked comment:
The reason why viewing the Summary tab causes the last-access time
to be updated is that the Summary tab retrieves its information
by calling StgOpenStorage
, and there’s no way to tell
that function,
“Hey, when you open the file in order to see if it has any
document properties, do that
DoNotUpdateLastAccessTime
thing so you don’t update the last access time.”
Bonus chatter: Starting in Windows Vista, maintaining the last-access time is disabled by default. In practice, this means that the number of bugs related to altering the last-access time accidentally will multiply unchecked, because the mechanism for detecting the error is disabled by default.
0 comments