Post by tsh73 on Feb 26, 2024 14:28:35 GMT -5
(really, if I were you I would just parse DIR output from
)
Ah well
Let's get file creation date with Windows API.
It looks working, but it's just pieces cobbled together
I hope (!) there is actually easier way.
Problem:
Windows explorer shows file timestamp - single timestamp
But file properties shows 3 timestamps:
file creation, file last write (==modification), file last access
And it looks like explorer shows modification date.
So is LB FILES command,
info$(1, 2)' - the file date/time stamp
is actually modification date.
How one gets creation date?
well, API
0) we need a file handle
calldll #kernel32, "CreateFileA"
1) getting fiel time.
calldll #kernel32, "GetFileTime"
actually returns all three timestamps (we could pass 0 for ones we don't need)
BUT
it is returned as a STRUCT. In the struct just two long integers (probably ULONG)
1.5) close that file. Because then your calldll will fail, it will get locked. So close it NOW!
calldll #kernel32, "CloseHandle"
2) getting time in readable format
calldll #kernel32, "FileTimeToSystemTime"
it unpacks these 2 integers into SYSTEMTIME struct (found here, thanks wexhammer)
And we actually could use day/month/hour/second etc from this struct.
BUT
I see that it is UTC time. Several hours off that is!
3) calldll #kernel32, "SystemTimeToTzSpecificLocalTime"
That's all.
But (1) needs a FILETIME struct
(2) needs a SYSTEMTIME struct
and (3) needs another SYSTEMTIME struct.
So it pretty long.
But seems working, have a look
dir /t:c filename.ext
)
Ah well
Let's get file creation date with Windows API.
It looks working, but it's just pieces cobbled together
I hope (!) there is actually easier way.
Problem:
Windows explorer shows file timestamp - single timestamp
But file properties shows 3 timestamps:
file creation, file last write (==modification), file last access
And it looks like explorer shows modification date.
So is LB FILES command,
info$(1, 2)' - the file date/time stamp
is actually modification date.
How one gets creation date?
well, API
0) we need a file handle
calldll #kernel32, "CreateFileA"
1) getting fiel time.
calldll #kernel32, "GetFileTime"
actually returns all three timestamps (we could pass 0 for ones we don't need)
BUT
it is returned as a STRUCT. In the struct just two long integers (probably ULONG)
1.5) close that file. Because then your calldll will fail, it will get locked. So close it NOW!
calldll #kernel32, "CloseHandle"
2) getting time in readable format
calldll #kernel32, "FileTimeToSystemTime"
it unpacks these 2 integers into SYSTEMTIME struct (found here, thanks wexhammer)
And we actually could use day/month/hour/second etc from this struct.
BUT
I see that it is UTC time. Several hours off that is!
3) calldll #kernel32, "SystemTimeToTzSpecificLocalTime"
That's all.
But (1) needs a FILETIME struct
(2) needs a SYSTEMTIME struct
and (3) needs another SYSTEMTIME struct.
So it pretty long.
But seems working, have a look
'Getting file creation date
' GetFileTime Win API demo
'based off
'https://www.easefilter.com/kb/fileapi-getfiletime.htm
'Win32 File API GetFileTime function
path1$="C:\wrk\test12106.txt"
'created 26.02.24 21:06:13, did not changed (change time the same)
path2$="C:\wrk\test12106copy.txt"
'copied 26.02.24 21:08, did not changed (change time BEFORE CREATION 26.02.24 21:06:13 !!)
dim info$(10, 10)
files "c:\", path1$, info$()
print "Files found "; info$(0, 0)
if val(info$(0, 0))=0 then 'no files found
print "So ";path1$;" does not exist"
else
print info$(1, 0)' - the file name
print info$(1, 2)' - the file date/time stamp
end if
print
files "c:\", path2$, info$()
print "Files found "; info$(0, 0)
if val(info$(0, 0))=0 then
notice "Set path2$ to some existing file name so program have something to play with"
end 'no files found
end if
print info$(1, 0)' - the file name
print info$(1, 2)' - the file date/time stamp
print
'so info$(1, 2) is last time changed
'-------------------------------------------
'
'https://www.easefilter.com/kb/fileapi-getfiletime.htm
'Win32 File API GetFileTime function
'FILETIME
'The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.
'typedef struct _FILETIME { // ft
'DWORD dwLowDateTime;
'DWORD dwHighDateTime;
'} FILETIME;
'typedef *FILETIME LPFILETIME
'declare a struct:
STRUCT ftCreate,_
dwLowDateTime as ulong,_
dwHighDateTime as ulong
STRUCT ftAccess,_
dwLowDateTime as ulong,_
dwHighDateTime as ulong
STRUCT ftWrite,_
dwLowDateTime as ulong,_
dwHighDateTime as ulong
'SYSTEMTIME from this thread
'https://libertybasiccom.proboards.com/thread/874/giving-little-back
'so it is actually Struct SYSTEMTIME
Struct stUTC, _
wYear As word, _
wMonth As word, _
wDayOfWeek As word, _
wDay As word, _
wHour As word, _
wMinute As word, _
wSecond As word, _
wMilliseconds As word
Struct stLocal, _
wYear As word, _
wMonth As word, _
wDayOfWeek As word, _
wDay As word, _
wHour As word, _
wMinute As word, _
wSecond As word, _
wMilliseconds As word
hFile = 0 'file handle
INVALID.HANDLE.VALUE = -1
'open a file for input
hFile = OpenForInput(path2$)
if hFile <> INVALID.HANDLE.VALUE then 'file opened successfully
print "File opened OK"
'to do smth
'calldll #kernel32, "GetFileTime", hFile as ulong, _
'ftCreate as struct, ftAccess as struct, ftWrite as struct, _
' ret as long
'if I need only ftCreate I could pass NULLs
calldll #kernel32, "GetFileTime", hFile as ulong, _
ftCreate as struct, 0 as ulong, 0 as ulong, _
ret as long
print "GetFileTime Ret="; ret
call CloseFile hFile 'close file or it could not be opened after error without LB reload
'print ftCreate.dwLowDateTime.struct
'print ftCreate.dwHighDateTime.struct
'print
'print ftWrite.dwLowDateTime.struct
'print ftWrite.dwHighDateTime.struct
calldll #kernel32, "FileTimeToSystemTime", ftCreate as struct, stUTC as struct, _
ret as long
print "FileTimeToSystemTime Ret="; ret
' print "File creation date is"
' print stUTC.wYear.struct;"-";
' print stUTC.wMonth.struct;"-";
' print stUTC.wDay.struct;" ";
' print stUTC.wHour.struct;":";
' print stUTC.wMinute.struct;":";
' print stUTC.wSecond.struct
'problem is, it was UTC time, severak hours off mine
'so once again
calldll #kernel32, "SystemTimeToTzSpecificLocalTime", 0 as ulong, stUTC as struct, _
stLocal as struct, ret as long
print "SystemTimeToTzSpecificLocalTime Ret="; ret
print "File creation date is"
print stLocal.wYear.struct;"-";
print stLocal.wMonth.struct;"-";
print stLocal.wDay.struct;" ";
print stLocal.wHour.struct;":";
print stLocal.wMinute.struct;":";
print stLocal.wSecond.struct
else
notice "File Access Error" + chr$(13) + "File could not be opened."
end if
end
'-------------------------------------------
function OpenForInput(fileName$)
'open a file for input.
calldll #kernel32, "CreateFileA", fileName$ as ptr, _GENERIC_READ as ulong, _
0 as ulong, 0 as long, _OPEN_EXISTING as ulong, _
_FILE_ATTRIBUTE_NORMAL as ulong, 0 as long, OpenForInput as long
end function
sub CloseFile hFile
calldll #kernel32, "CloseHandle", hFile as long, r as long
end sub