HOWTO: Get Extended File Time Information Using the Win32 API

Last reviewed: July 14, 1997
Article ID: Q154821
The information in this article applies to:
  • Microsoft Visual Basic Professional and Enterprise Editions for Windows, version 5.0
  • Standard, Professional, and Enterprise Editions of Microsoft Visual Basic, 32-bit only, for Windows, version 4.0

SUMMARY

Windows NT and Windows 95 store additional information about a file, including the time and date that the file was last accessed. This information cannot be accessed with the FileDateTime API function but can be extracted using a combination of calls to the Windows API. This article describes how to accomplish this behavior.

MORE INFORMATION

The creation time, last-written time, and the last-accessed (read) time of a file are all stored in 32-bit Windows, but only the time and date of the last write to the file are accessible directly from Visual Basic.

The API function used expects to be passed a system file handle rather than a Visual Basic file number. However, due to a limitation in 32-bit Visual Basic, the FileAttr function is incapable of returning an operating system file handle and API calls must be used to open the file. To obtain this data, do the following:

  1. Start a new Visual Basic project. Form1 is created by default.

  2. Add a text box control to Form1. It is called Text1 by default.

  3. Add a CommandButton to Form1. It is called Command1 by default

  4. Add the following code to the General Declarations section of Form1:

    Option Explicit

    Private Const OF_READ = &H0 Private Const OF_SHARE_DENY_NONE = &H40 Private Const OFS_MAXPATHNAME = 128

    Private Type OFSTRUCTREC

         cBytes As Byte
         fFixedDisk As Byte
         nErrCode As Integer
         Reserved1 As Integer
         Reserved2 As Integer
         szPathName(OFS_MAXPATHNAME) As Byte
    
    End Type

    Private Type FILETIMEREC

         dwLowDateTime As Long
         dwHighDateTime As Long
    
    End Type

    Private Type SYSTEMTIMEREC

         wYear As Integer
         wMonth As Integer
         wDayOfWeek As Integer
         wDay As Integer
         wHour As Integer
         wMinute As Integer
         wSecond As Integer
         wMilliseconds As Integer
    
    End Type

       Private Declare Function FileTimeToSystemTime Lib "kernel32" _
         (lpFileTime As FILETIMEREC, lpSystemTime As SYSTEMTIMEREC) As Long
       Private Declare Function GetFileTime Lib "kernel32" (ByVal _
         hFile As Long, lpCreationTime As FILETIMEREC, lpLastAccessTime _
         As FILETIMEREC, lpLastWriteTime As FILETIMEREC) As Long
       Private Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As _
         String, lpReOpenBuff As OFSTRUCTREC, ByVal wStyle As Long) As Long
       Private Declare Function hread Lib "kernel32" Alias "_hread" _
         (ByVal hFile As Long, lpBuffer As Any, ByVal lBytes As Long) As Long
       Private Declare Function lclose Lib "kernel32" Alias "_lclose" (ByVal _
         hFile As Long) As Long
    
       Sub Form_Load()
         Command1.Caption = "&Get file access time"
         Text1.Text = "C:\AUTOEXEC.BAT"
       End Sub
    
       Private Sub Command1_Click()
         Dim sInpFile As String
         Dim hFile As Integer
         Dim FileStruct As OFSTRUCTREC
         Dim iRC As Integer
         Dim CreationTime As FILETIMEREC
         Dim LastAccessTime As FILETIMEREC
         Dim LastWriteTime As FILETIMEREC
         Dim SystemTime As SYSTEMTIMEREC
         sInpFile = Trim(Text1.Text)
         ' check that the file exists
         If Len(Dir(sInpFile)) = 0 Then
           MsgBox "Can't find the file", vbExclamation
           Exit Sub
         End If
    
         ' Open it to get a stream handle
         hFile = OpenFile(sInpFile, FileStruct, OF_READ Or OF_SHARE_DENY_NONE)
         If hFile = 0 Then
           MsgBox "Can't open the file", vbExclamation
           Exit Sub
         End If
    
         If GetFileTime(hFile, CreationTime, _
             LastAccessTime, LastWriteTime) Then
               ' massage time into format that we can use
           If Not FileTimeToSystemTime(LastAccessTime, SystemTime) Then
             Print "Year of file  :" & SystemTime.wYear
             Print "Month of File :" & SystemTime.wMonth
             Print "Day of File   :" & SystemTime.wDay
           Else
             MsgBox "FileTimeToSystemTime Failed"
           End If
         Else
           MsgBox "GetFileTime Failed"
         End If
    
         iRC = lclose(hFile)
       End Sub
    
    

  5. Run the program by pressing the F5 key or clicking the Play button. Enter a filename in the text box, including path if necessary, and click the CommandButton.

Note that the last written time and file creation time are returned. The code could be extended to return the Time information as well as the Date information shown. These values are returned in the SYSTEMTIME record.

The FAT and New Technology file systems support the file creation, last access, and last write time values. Under Windows 95, the precision of the time for a file in a FAT file system is 2 seconds. The time precision for files in other file systems, such as those connected through a network, depends on the file system but may also be limited by the remote device.

REFERENCES

The Win32 SDK has additional information about the APIs used in the code above.


Keywords : APrgOther vb432 vb4win vb5all kbhowto
Version : 4.0 5.0
Platform : NT WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 14, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.