|
-
Sep 14th, 2014, 06:09 AM
#1
[RESOLVED] Search hard drives for all files in a listbox
Hi,
How would I do a reclusive search to search all the drives on a machines for files I have listed in listbox? I have searched but the code I came across did not work.
Thanks,
Nightwalker
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Sep 14th, 2014, 06:29 AM
#2
Re: Search hard drives for all files in a listbox
-
Sep 14th, 2014, 06:50 AM
#3
Re: Search hard drives for all files in a listbox
Yes, although, I need to search by file name and extension.
Edit:
The file names and extension will be listed in a listbox.
Last edited by Nightwalker83; Sep 14th, 2014 at 06:52 AM.
Reason: Adding more!
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Sep 14th, 2014, 09:51 AM
#4
Re: Search hard drives for all files in a listbox
There's Directory-ListClasses which support multiple wildcard-containing filters -
and the fully qualified filenames (without wildcards) could be matched against a
Hash-List (e.g. a VB.Collection - or faster alternatives).
But before helping ntshki with more concrete code - I think he should answer
a few questions first (which I just raised in the appropriate thread):
http://www.vbforums.com/showthread.p...and-Sub-Folder
Olaf
-
Sep 14th, 2014, 08:24 PM
#5
Re: Search hard drives for all files in a listbox
 Originally Posted by Schmidt
There's Directory-ListClasses which support multiple wildcard-containing filters -
and the fully qualified filenames (without wildcards) could be matched against a
Hash-List (e.g. a VB.Collection - or faster alternatives).
Where is it?
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Sep 14th, 2014, 09:51 PM
#6
Re: Search hard drives for all files in a listbox
 Originally Posted by Nightwalker83
Where is it?
E.g. vbRichClient5 contains such Classes
An unicode-aware solution for the whole problem could be written up this way:
Code:
Private Sub Form_Load()
'simply put the Filenames *without* Wildcards into a Dictionary, which allows for fast Exists-Checks
Dim CompareList As cSortedDictionary
Set CompareList = New_c.SortedDictionary(TextCompare)
CompareList.Add "Test.vbp"
CompareList.Add "modMain.bas"
'etc...
Dim Results As cCollection
Set Results = New_c.Collection 'create an instance which takes up the results
'and the list of WildCard-Filters needs to be Semicolon-separated
DirScanRecursive "C:", "*.vbp; *.frm; *.bas; *.cls; *.ctl", CompareList, Results
End Sub
Private Sub DirScanRecursive(ByVal DirPath As String, Filters As String, _
CompareList As cSortedDictionary, Results As cCollection)
Dim i As Long, DL As cDirList
On Error GoTo SkipAccessDenied
Set DL = New_c.FSO.GetDirList(DirPath, , Filters)
On Error GoTo 0
For i = 0 To DL.FilesCount - 1
If CompareList.Exists(DL.FileName(i)) Then Results.Add DL.Path & DL.FileName(i)
Next i
For i = 0 To DL.SubDirsCount - 1
DirScanRecursive DL.Path & DL.SubDirName(i), Filters, CompareList, Results
Next i
SkipAccessDenied:
End Sub
Needs about 3.5seconds here in a repeated run over my whole C: Drive.
(first run took about 3 times as long, due to a not yet warmed-up Windows-Filecache).
Olaf
-
Sep 14th, 2014, 10:55 PM
#7
Re: Search hard drives for all files in a listbox
How do I display the results?
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Sep 15th, 2014, 06:13 AM
#8
Re: Search hard drives for all files in a listbox
The Results are gathered in a cCollection (which is by default instantiated with its
Property .CompatibleToVBCollection = True)
So you can enumerate per For Each - as well as per OneBased Index -
exactly as you would do with a VB.Collection:
Code:
Dim Result, i As Long
'For Each Enumeration
For Each Result In Results
Debug.Print Result
Next
'Enumeration per OneBased Index
For i = 1 To Results.Count
Debug.Print Results(i)
Next
'Enumeration per ZeroBased Index
For i = 0 To Results.Count - 1
Debug.Print Results.ItemByIndex(i)
Next
Olaf
-
Sep 15th, 2014, 10:29 AM
#9
Re: Search hard drives for all files in a listbox
You can also query the Windows Search indexes using a fairly complex form of SQL. You can limit queries to a directory and do deep or shallow searches, or query all filesystem indexes. You can search for a list of item names, or do wildcard searches, or even full-text searches and more.
Querying the local catalog is simple, but you can also query other PCs on your network as well.
Here if txtFolder.Text is empty all drives' indexes are searched:
Code:
Set CN = New ADODB.Connection
CN.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows'"
...
With cboFiles
If .ListCount > 0 Then
For I = 0 To .ListCount - 1
List = List & " OR System.ItemNameDisplay='" & .List(I) & "'"
Next
List = " AND (" & Mid$(List, 5) & ")"
End If
End With
CN.Execute "SELECT TOP " & CStr(RowLimit) _
& " System.ItemNameDisplay," _
& "System.Size," _
& "System.Kind," _
& "System.KindText," _
& "System.ItemType," _
& "System.ItemTypeText," _
& "System.ItemFolderPathDisplay," _
& "System.ItemPathDisplay" _
& " FROM SystemIndex" _
& " WHERE SCOPE='file:" & Replace$(Trim$(txtFolder.Text), "\", "/") & "'" _
& " AND System.Kind <> 'folder'" _
& List, _
, _
adCmdText Or adAsyncExecute
Then in the Connection's ExecuteComplete event handler you have an ADO Recordset you can work with.
The only real limitation is that it only searches indexed locations, but for most applications that's all you need anyway. But in addition to the "file:" protocol you can also search mail ("mapi:"), the offline files catalog ("csc:"), or even other index catalogs if an application has added a Search protocol handler for it.
I'm surprised this isn't used more. After all you pay the price for Windows to do this indexing, why not use it? You can do a lot of things with it, e.g. a photo viewer application can search for images greater than 1000 pixels wide, taken with a certain camera, between a range of dates, ... above a certain altitude if the camera recorded that data in the EXIF info.
-
Sep 15th, 2014, 01:50 PM
#10
Re: Search hard drives for all files in a listbox
http://www.vbforums.com/showthread.p...=1#post4757425
I posted there for folders, but the class work for files too.
About RecDir class: All the tree of files (and folders) populate a list. Folders are marked in first char. Only folder include path. There is a simple function to show the path of a file if randomly pick one. But if we start from the start then we have always the folder name first, files and then sub folders, and for each sub folder, first the path, files and sub folders. So anytime before files is the folder path. We don't need to find where is a folder because for each folder we put the full path. Because this I made for file/folder selector I only put file type (if we wish) to make the validation (for files only). But it is easy to alter this to valid only a list of names (for that reason a string with chars like this # between for known files and the use of instr function can be help)
-
Sep 16th, 2014, 03:32 AM
#11
Re: Search hard drives for all files in a listbox
 Originally Posted by georgekar
I posted there for folders, but the class work for files too.
I could not figure out what I need to modify to get the class to work with files instead of folders?
Edit:
 Originally Posted by Schmidt
The Results are gathered in a cCollection (which is by default instantiated with its
Property .CompatibleToVBCollection = True)
Neither the Result or Results have anything in them when I view them in the debugger during executing the DirScanRecursive sub, what am I missing?
Last edited by Nightwalker83; Sep 16th, 2014 at 04:47 AM.
Reason: Adding more!
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Sep 16th, 2014, 05:17 AM
#12
Re: Search hard drives for all files in a listbox
There is a flag Nofiles...When NoFiles if True then No Files are listed. (I put No in front a flag to remember that it works inverted, false to get what it says...so NoFiles = False means with files..)
-
Sep 16th, 2014, 06:37 AM
#13
Re: Search hard drives for all files in a listbox
 Originally Posted by Nightwalker83
Neither the Result or Results have anything in them when I view them in the debugger during executing the DirScanRecursive sub, what am I missing?
If you didn't change any of the TestFilter-settings - and left the entries in the CompareList
as they were in my posted example, then the scan filters for "typical VB-Files first" -
AND doesn't put anything into the Results-Collection, as long as there were no exact
FileName-Matches *in addition*.
So the posted example is currently behaving with an AND-condition (a wildcard-based
pre-filtering - followed by a concrete FileName-comparison on all Files which made it
through the first Filter-stage.
If you want to make it behave more like an OR comparison (either partial wildcard-match
OR full filename-match) - then you could handle this OR case in one pass - by doing your own
Like-comparisons against the entries in a self-managed Wildcardlist-Array.
Though to make use of what we have already, we can perform the whole thing in "two passes" -
prolonging the Results-Collection with additional entries in the second pass... the behaviour
then resembling an SQL-Union-Query somewhat...
The DirScanRecursive-routine needs only a small addition to handle this new case -
when we call the procedure without a present CompareList-Parameter (when it's at Nothing).
Code:
Private Sub Form_Load()
Dim WildCardFilters As String, CompareList As cSortedDictionary, Results As cCollection
Set Results = New_c.Collection 'create an instance which will take up the results
WildCardFilters = Join(Array("*.vbp", "*.frm", "*.bas", "*.cls", "*.ctl"), ";")
'first pass will do Results.Add on all the Files which match with the WildCard-Filterlist above
DirScanRecursive "C:", WildCardFilters, Nothing, Results '(note that CompareList-Param is Nothing)
Debug.Print "first pass Results-Count: "; Results.Count
'prepare a "non-wildcard-comparelist" in a Dictionary, which allows for fast Exists-Checks
Set CompareList = New_c.SortedDictionary(TextCompare)
CompareList.Add "Test.vbp"
CompareList.Add "modMain.bas"
'etc...
'second pass, now only using Filename-Comparison against the entries in CompareList
DirScanRecursive "C:", "", CompareList, Results '(CompareList is not empty, but the WildCard-FilterString is)
Debug.Print "second pass increased the Results-Count to: "; Results.Count
End Sub
Private Sub DirScanRecursive(ByVal DirPath As String, Filters As String, _
CompareList As cSortedDictionary, Results As cCollection)
Dim i As Long, DL As cDirList
On Error GoTo SkipAccessDenied
Set DL = New_c.FSO.GetDirList(DirPath, , Filters)
On Error GoTo 0
If CompareList Is Nothing Then 'we add all files which made it through the WildcardFilters
For i = 0 To DL.FilesCount - 1
Results.Add DL.Path & DL.FileName(i)
Next i
Else 'additional check (we only add Files, when they are contained in the CompareList)
For i = 0 To DL.FilesCount - 1
If CompareList.Exists(DL.FileName(i)) Then Results.Add DL.Path & DL.FileName(i)
Next i
End If
For i = 0 To DL.SubDirsCount - 1
DirScanRecursive DL.Path & DL.SubDirName(i), Filters, CompareList, Results
Next i
SkipAccessDenied:
End Sub
Olaf
Last edited by Schmidt; Sep 16th, 2014 at 06:50 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|