Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Full Path filenames of directory and it's subdirectories 3

Status
Not open for further replies.

Kiehlster

MIS
Aug 14, 2000
147
US
Is there any way with visual basic to get a list of full pathnames of files in a directory and that directory's subdirectories, and have the list sent to a file? The only way I have seen is to call a shell and do a <br><br>&quot;dir /B /S &gt; myfile.txt&quot;<br><br>and I have this huge subroutine that it has to go through in order to tell the file is completely done writing to the disk.&nbsp;&nbsp;Any easier way than that?
 
This works very well, thanks to Mike Lacey who pointed me towards the code.<br><br><b><FONT FACE=monospace>'Module level code<br>Option Explicit <br>Const MAX_PATH = 260 <br>Const INVALID_HANDLE_VALUE = -1 <br>Const FILE_ATTRIBUTE_DIRECTORY = &H10 <br><br>Type FILETIME <br>&nbsp;&nbsp;&nbsp;dwLowDateTime As Long <br>&nbsp;&nbsp;&nbsp;dwHighDateTime As Long <br>End Type <br><br>Type WIN32_FIND_DATA <br>&nbsp;&nbsp;&nbsp;dwFileAttributes As Long <br>&nbsp;&nbsp;&nbsp;ftCreationTime As FILETIME <br>&nbsp;&nbsp;&nbsp;ftLastAccessTime As FILETIME <br>&nbsp;&nbsp;&nbsp;ftLastWriteTime As FILETIME <br>&nbsp;&nbsp;&nbsp;nFileSizeHigh As Long <br>&nbsp;&nbsp;&nbsp;nFileSizeLow As Long <br>&nbsp;&nbsp;&nbsp;dwReserved0 As Long <br>&nbsp;&nbsp;&nbsp;dwReserved1 As Long <br>&nbsp;&nbsp;&nbsp;cFileName As String * MAX_PATH <br>&nbsp;&nbsp;&nbsp;cAlternate As String * 14 <br>End Type <br><br>Type FOLDER_INFO <br>&nbsp;&nbsp;&nbsp;DirSize As Currency <br>&nbsp;&nbsp;&nbsp;FilesCount As Long <br>&nbsp;&nbsp;&nbsp;DirsCount As Long <br>End Type <br><br>Declare Function FindFirstFile Lib &quot;kernel32&quot; Alias &quot;FindFirstFileA&quot; (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long <br>Declare Function FindNextFile Lib &quot;kernel32&quot; Alias &quot;FindNextFileA&quot; (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long <br>Declare Function FindClose Lib &quot;kernel32&quot; (ByVal hFindFile As Long) As Long <br>Public sFiles() As String <br><br>Public Function GetFolderInfo(sFolder As String, Optional sPattern As String = &quot;*.*&quot;) As FOLDER_INFO <br>&nbsp;&nbsp;&nbsp;If Right$(sFolder, 1) &lt;&gt; &quot;\&quot; Then sFolder = sFolder & &quot;\&quot; <br>&nbsp;&nbsp;&nbsp;Dim lFileNum As Long, lDirNum As Long, sTemp As String <br>&nbsp;&nbsp;&nbsp;Dim curSize As Currency, FolderQueue As New Collection <br>&nbsp;&nbsp;&nbsp;FolderQueue.Add sFolder <br>&nbsp;&nbsp;&nbsp;Call EnumFolder(FolderQueue) <br>&nbsp;&nbsp;&nbsp;sTemp = FolderQueue.Item(1) <br>&nbsp;&nbsp;&nbsp;Call EnumFiles(sTemp, lFileNum, curSize, sPattern) <br>&nbsp;&nbsp;&nbsp;FolderQueue.Remove 1 <br>&nbsp;&nbsp;&nbsp;Do While FolderQueue.Count &gt; 0 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lDirNum = lDirNum + 1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call EnumFolder(FolderQueue) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sTemp = FolderQueue.Item(1) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Call EnumFiles(sTemp, lFileNum, curSize, sPattern) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FolderQueue.Remove 1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DoEvents <br>&nbsp;&nbsp;&nbsp;Loop <br>&nbsp;&nbsp;&nbsp;GetFolderInfo.DirSize = curSize <br>&nbsp;&nbsp;&nbsp;GetFolderInfo.FilesCount = lFileNum <br>&nbsp;&nbsp;&nbsp;GetFolderInfo.DirsCount = lDirNum <br>End Function <br><br>Private Sub EnumFolder(FolderQueue As Collection) <br>&nbsp;&nbsp;&nbsp;Dim sTemp As String, sFolder As String <br>&nbsp;&nbsp;&nbsp;Dim lRet As Long, WFD As WIN32_FIND_DATA <br>&nbsp;&nbsp;&nbsp;Dim hFile As Long <br>&nbsp;&nbsp;&nbsp;sFolder = FolderQueue.Item(1) <br>&nbsp;&nbsp;&nbsp;hFile = FindFirstFile(sFolder & &quot;*.*&quot;, WFD) <br>&nbsp;&nbsp;&nbsp;If hFile = INVALID_HANDLE_VALUE Then Exit Sub <br>&nbsp;&nbsp;&nbsp;sTemp = TrimNulls(WFD.cFileName) <br>&nbsp;&nbsp;&nbsp;Do While sTemp &lt;&gt; &quot;&quot; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If (WFD.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY Then <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If sTemp &lt;&gt; &quot;.&quot; And sTemp &lt;&gt; &quot;..&quot; Then <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If Right$(sTemp, 1) &lt;&gt; &quot;\&quot; Then sTemp = sTemp & &quot;\&quot; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FolderQueue.Add sFolder & sTemp <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lRet = FindNextFile(hFile, WFD) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sTemp = &quot;&quot; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If lRet &lt;&gt; 0 Then sTemp = TrimNulls(WFD.cFileName) <br>&nbsp;&nbsp;&nbsp;Loop <br>&nbsp;&nbsp;&nbsp;lRet = FindClose(hFile) <br>End Sub <br><br>Private Sub EnumFiles(sFolder As String, lFileNum As Long, lngSize As Currency, sPattern As String) <br>&nbsp;&nbsp;&nbsp;Dim sTemp As String <br>&nbsp;&nbsp;&nbsp;Dim lRet As Long, WFD As WIN32_FIND_DATA <br>&nbsp;&nbsp;&nbsp;Dim hFile As Long, n As Integer <br>&nbsp;&nbsp;&nbsp;hFile = FindFirstFile(sFolder & sPattern, WFD) <br>&nbsp;&nbsp;&nbsp;If hFile = INVALID_HANDLE_VALUE Then Exit Sub <br>&nbsp;&nbsp;&nbsp;sTemp = TrimNulls(WFD.cFileName) <br>&nbsp;&nbsp;&nbsp;Do While sTemp &lt;&gt; &quot;&quot; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lngSize = lngSize + WFD.nFileSizeLow <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lFileNum = lFileNum + 1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = UBound(sFiles) + 1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReDim Preserve sFiles(n) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sFiles(n) = sFolder & TrimNulls(WFD.cFileName) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lRet = FindNextFile(hFile, WFD) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sTemp = &quot;&quot; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If lRet &lt;&gt; 0 Then sTemp = TrimNulls(WFD.cFileName) <br>&nbsp;&nbsp;&nbsp;Loop <br>&nbsp;&nbsp;&nbsp;lRet = FindClose(hFile) <br>End Sub <br><br>Private Function TrimNulls(sTemp As String) As String <br>&nbsp;&nbsp;&nbsp;Dim l As Long <br>&nbsp;&nbsp;&nbsp;l = InStr(1, sTemp, Chr(0)) <br>&nbsp;&nbsp;&nbsp;If l = 1 Then <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TrimNulls = &quot;&quot; <br>&nbsp;&nbsp;&nbsp;ElseIf l &gt; 0 Then <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TrimNulls = Left$(sTemp, l - 1) <br>&nbsp;&nbsp;&nbsp;Else <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TrimNulls = sTemp <br>&nbsp;&nbsp;&nbsp;End If <br>End Function <br><br><br>'Form level code<br>Private Sub Command1_Click() <br>&nbsp;&nbsp;&nbsp;ReDim sFiles(0) <br>&nbsp;&nbsp;&nbsp;Dim l As FOLDER_INFO <br>&nbsp;&nbsp;&nbsp;l = GetFolderInfo(&quot;c:\&quot;, &quot;*.*&quot;) <br>&nbsp;&nbsp;&nbsp;MsgBox &quot;Total&nbsp;&nbsp;&quot; & l.DirSize & &quot; bytes&quot; & &quot; in &quot; & l.FilesCount & &quot; files at &quot; & l.DirsCount & &quot; Folders&quot; <br>'sFiles() array contains the full path to all files on C: <br>&nbsp;&nbsp;&nbsp;For i = 1 To UBound(sFiles) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Debug.Print sFiles(i) <br>&nbsp;&nbsp;&nbsp;Next i <br>End Sub <br></b></font> <p> <br><a href=mailto: > </a><br><a href= plain black box</a><br>
 
Check out M$ Scripting Runtime objects, they should have what you need.<br><br>If you have it it'll be in the <b>Project Reference</b> dialog list, just click the box.<br><br>Use the object browser to see the classes and properties it provides there are a small bunch.&nbsp;&nbsp;<br><br>As far as linking to the kernal vai the API... It's faster.&nbsp;&nbsp;I think the Scripting library gives you more than you need... but then again making a list is only the start of something much bigger.<br> <p>Wil Mead<br><a href=mailto:wmead@optonline.net>wmead@optonline.net</a><br><a href= > </a><br>
 
Thanks Wil.&nbsp;&nbsp;That should help me out a bit.&nbsp;&nbsp;Alt225, thanks anyway, but I don't really want to have to add all the code to my already huge length of code.&nbsp;&nbsp;I think Wil's suggestion will work best.&nbsp;&nbsp;All the functions are in there to get various file information and whatnot.<br><br>Thanks,<br>Steve Kiehl<br>Webmaster, <b><i>Nanovox</i>.com</b>
 
That's all right, Kiehlster, I'm here to help. But you might think again about using the scripting library if you just want to avoid adding more code. If you succeed in reproducing &quot;dir /B /S&quot; with less code than I posted above, I hope you will post it here. I love succinct solutions and am eager to add new ones to my toolbox.<br> <p> <br><a href=mailto: > </a><br><a href= plain black box</a><br>
 
actually, I did manage to get the &quot;dir /B /S&quot; style of doing it to run with only two main functions! I don't have time now, but I will post it up here sometime...Maybe under the FAQ. The only thing I have to work on with it is to find a way to get the file size. right now I have it loading the file until the last line of the file doesn't change anymore. That seems to work. But I think there could be a couple small problems with it. I think I might just try and see if VB picks up the size of the file before it is finished writing the file, because on a file that ends up to be 18mb.... ick.
 
Sorry I misunderstood. From your use of the &quot;/S&quot; switch on the DIR statement I thaought you had intended to perform a recursive sub-directory search.

You can determine the size of an open file with the Lof function.

F1 =FreeFile
Open &quot;C:\WINDOWS\WIN.COM&quot; For Binary as #F1
MsgBox &quot;Win.com is&quot; & Lof(F1) & &quot; bytes long.&quot;
Close #F1

For files that haven't been opened by your program use FileLen.

MsgBox &quot;The swap file is&quot; & _
[tab]FileLen(&quot;C:\WINDOWS\WIN386.SWP&quot;) & &quot; bytes long.&quot;
 
Sorry I didn't explain that too clearly. I was talking about the length of the file that the dos prompt outputs when I have it sent to a file. I've posted the solution I came up with in the FAQ, and thanks for the tip on the file length thing. It makes the solution even smaller and easier. You can see the FAQ in here, it's called:

How do get a recursive list of files, and wait for a DOS prompt to finish. (This easy way)

I messed up on the title a little bit and I can't fix it now. argh.

Thanks again, and I hope that the FAQ I posted helps or at least makes you think again on how easy things really can be.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top