You can use filer that comes with VFP. ie:
lcStartDir = HOME()
*lnFiles = GetTree(lcStartDir,'*.dbf;*.cdx;*.fpt', 'myCursor', .t.)
lnFiles = GetTree(lcStartDir,'*.*', 'myCursor', .t.)
Local array arrSizeTot[1]
Select sum(FileSize) from myCursor into array arrSizeTot
trans(iif(_Tally>0,arrSizeTot,0))+' bytes in '+trans(m.lnFiles)+' files.'
Select * ;
from myCursor ;
order by filepath, Isfolder desc, Filename
Function GetTree
Lparameters tcStartDir,tcSkeleton,tcCursorName,;
tlSubfolders,;
tlWholeWords,tlIgnoreCase,tlSearchAnd,tcSearch1,tcSearch2,tcSearch3
Create Cursor (tcCursorName) ;
(filepath c(250), filename c(250), ;
FileSize i, fattr c(8), createtime T, lastacc T, lastwrite T, IsFolder l)
Local oFiler, lnFound
oFiler = Createobject('filer.fileutil')
With oFiler
.SearchPath = tcStartDir
.FileExpression = tcSkeleton && Search for skeleton
.Subfolder = iif(tlSubfolders,1,0) && Check subfolders
.IgnoreCase = iif(tlIgnoreCase,1,0)
.WholeWords = iif(tlWholeWords,1,0)
.SearchAnd = iif(tlSearchAnd,1,0)
.SearchText1 = iif(empty(tcSearch1),"",tcSearch1)
.SearchText2 = iif(empty(tcSearch2),"",tcSearch2)
.SearchText3 = iif(empty(tcSearch3),"",tcSearch3)
lnFound = .Find(0)
For ix=1 To lnFound
With .Files(ix)
If !(Bittest(.Attr,4) And .Name = '.')
Insert Into (tcCursorName) ;
(filepath, filename, FileSize, fattr, createtime, lastacc, lastwrite,IsFolder) ;
values ;
(.Path, .Name, .Size, Attr2Char(.Attr), ;
Num2Time(.Datetime), Num2Time(.LastAccessTime), Num2Time(.LastWriteTime),Bittest(.Attr,4))
IF Bittest(.Attr,4)
WAIT WINDOW NOWAIT "Folder: "+.Path
endif
Endif
Endwith
Endfor
ENDWITH
WAIT clear
Return lnFound
Function Num2Time
Lparameters tnFloat
Return Dtot({^1899/12/30}+Int(tnFloat))+86400*(tnFloat-Int(tnFloat))
Function Attr2Char
Lparameters tnAttr
Return ;
IIF(Bittest(tnAttr,0),'RO','RW')+;
IIF(Bittest(tnAttr,1),'H','_')+;
IIF(Bittest(tnAttr,2),'S','_')+;
IIF(Bittest(tnAttr,4),'D','_')+;
IIF(Bittest(tnAttr,5),'A','_')+;
IIF(Bittest(tnAttr,6),'E','_')+;
IIF(Bittest(tnAttr,7),'N','_')