Speed is just one feature that make the "shell out to dir" approach attractive;
depending on your task and the context, filtering by wildcards, ordering, or
even the recursive traversal (/s) may make your task easier.
If you (can) get rid of the .bat files and the array, the code is easy and
maintainable - e.g.:
Dim sDir : sDir = "C:\WINDOWS\system32"
Dim sPat : sPat = "\x*.dll"
Dim sOrd : sOrd = "/o:n"
Dim sCmd : sCmd = "%comspec% /c dir /b " & sOrd & " """ & sDir & sPat & """"
WScript.Echo sCmd
Dim oExec : Set oExec = CreateObject("WScript.Shell").Exec(sCmd)
Do Until oExec.Status = cnWshFinished
If Not oExec.StdOut.AtEndOfStream Then
WScript.Echo oExec.StdOut.ReadLine()
End If
Loop
Do Until oExec.StdOut.AtEndOfStream
WScript.Echo oExec.StdOut.ReadLine()
Loop
Instead of an array, you could use a disconnected recordset:
Sub AddFileTo(oRS, oFile)
oRS.AddNew
oRS.Fields( "sPath" ).Value = oFile.Path
oRS.Fields( "sName" ).Value = oFile.Name
oRS.Fields( "lSize" ).Value = oFile.Size
oRS.Fields( "dtLMod" ).Value = oFile.DateLastModified
oRS.Update
End Sub
Dim sDir : sDir = "C:\WINDOWS\system32"
Dim oRS : Set oRS = CreateObject("ADODB.RecordSet")
oRS.Fields.Append "sPath" , adVarWChar, 255
oRS.Fields.Append "sName" , adVarWChar, 255
oRS.Fields.Append "lSize" , adInteger
oRS.Fields.Append "dtLMod", adDate
oRS.Open
Dim oFile
For Each oFile In goFS.GetFolder(sDir).Files
AddFileTo oRS, oFile
Next
oRS.Sort = "dtLMod" ' "lSize" ' "sName"
oRS.MoveFirst
Do Until oRS.EOF
WScript.Echo oRS.GetString( adClipString, 1, vbCrLf, vbCrLf, "<Null>")
Loop
That's especially attractive, if you need the data in a collection that
can be processed/displayed in different orders. Another sample, this time
using dir /s:
Dim sDir : sDir = "C:\Perl"
Dim sPat : sPat = "" ' "\*.xls" ' "\x*.dll"
Dim sCmd : sCmd = "%comspec% /c dir /a:-d /-c /s /t:a """ & sDir & sPat & """"
WScript.Echo sCmd
Dim reCut : Set reCut = New cRE.initPF(_
"^(?:\sDirectory\sof\s(.*?))\s*$|^(\d\d).(\d\d).(\d{4})\s+(\d\d):(\d\d)\s+(\d+)\s+(.*?)\s*$", "gimx" _
)
Dim oMTS, sStaticPath
Dim oExec : Set oExec = CreateObject("WScript.Shell").Exec(sCmd)
Dim oRS : Set oRS = CreateObject("ADODB.RecordSet")
oRS.Fields.Append "sPath" , adVarWChar, 255
oRS.Fields.Append "sName" , adVarWChar, 255
oRS.Fields.Append "lSize" , adInteger
oRS.Fields.Append "dtLMod", adDate
oRS.Open
Do Until oExec.Status = cnWshFinished
If Not oExec.StdOut.AtEndOfStream Then
AddMtsTo oRS, reCut.Execute(oExec.StdOut.ReadLine()), sStaticPath
End If
Loop
Do Until oExec.StdOut.AtEndOfStream
AddMtsTo oRS, reCut.Execute(oExec.StdOut.ReadLine()), sStaticPath
Loop
If Not oRS.EOF Then
oRS.Sort = "dtLMod" ' "lSize" ' "sName"
oRS.MoveFirst
Do Until oRS.EOF
WScript.Echo oRS.GetString( adClipString, 1, vbCrLf, vbCrLf, "<Null>")
Loop
End If
and the corresponding Add Sub:
Sub AddMtsTo(oRS, oMTS, sStaticPath)
If 1 = oMTS.Count Then
If "" = oMTS(0).SubMatches(0) Then
Dim dtX : dtX = DateSerial( _
CInt(oMTS(0).SubMatches(3)), CByte(oMTS(0).SubMatches(2)), CByte(oMTS(0).SubMatches(1)) _
) + TimeSerial( _
CByte(oMTS(0).SubMatches(4)), CByte(oMTS(0).SubMatches(5)), 0 _
)
oRS.AddNew
oRS.Fields( "sPath" ).Value = sStaticPath
oRS.Fields( "sName" ).Value = oMTS(0).SubMatches(7)
oRS.Fields( "lSize" ).Value = CLng(oMTS(0).SubMatches(6))
oRS.Fields( "dtLMod" ).Value = dtX
oRS.Update
Else
sStaticPath = oMTS(0).SubMatches(0)
End If
End If
End Sub