AllAPI Network - The KPD-Team

 
Allapi Network
 API-Guide
 ApiViewer

 API List

 
API Resources
 Tips & Tricks
 VB Tutorials
 Error Lookup
 
Misc Stuff
 VB examples
 VB Tools
 VB Links
 Top Downloads
 
This Site
 Search Engine
 Contact Form
 

Donate to AllAPI.net

How to find files using Windows API

This article is written by Steve Anderson.
Author: Steve Anderson
Email: steve@microweird.demon.co.uk
Internet: http://www.microweird.demon.co.uk

Steve also offers a free Visual Basic Mailing list that contains lots of source code and other related Visual Basic Articles.  You can join this mailing list by sending an email to listserv@microweird.demon.co.uk with the word 'subscribe' in the subject line.

When writing a program, you may require the user to have a certain program installed. It may be that you have a written an application that requires Microsoft Word. When you run your program you may want to check whether the user has this application installed. To do this a programmer would generally use three methods.

  • Check the registry for a program
  • Check for an INI file which is usually located in the Windows directory
  • Search for a specific program filename.
These methods depend on the program that you are looking for. One of the best ways, is to search for a programs filename. Visual Basic includes a demo project called Seek that does a similar job, which is in the samples directory of Visual Basic. This is not very good though in an application, because it has to use the drive, folder and file list boxes. It is much better to do this with Windows API. I have included an example below.

1. Start a new Standard EXE project in Visual Basic. Form1 is created by default.

2. Add a command button named Command1, four text boxes named Text1, Text2, Text3 and Text4 and a list box to Form1.

3. Add a Module from the Projects menu and insert the following:

Declare Function FindFirstFile Lib "kernel32" Alias _
"FindFirstFileA" (ByVal lpFileName As String, lpFindFileData _
As WIN32_FIND_DATA) As Long            

Declare Function FindNextFile Lib "kernel32" Alias _
"FindNextFileA" (ByVal hFindFile As Long, _
lpFindFileData As WIN32_FIND_DATA) As Long            

Declare Function GetFileAttributes Lib "kernel32" Alias _
"GetFileAttributesA" (ByVal lpFileName As String) As Long            

Declare Function FindClose Lib "kernel32" (ByVal hFindFile _
As Long) As Long            

Public Const MAX_PATH = 260
Public Const MAXDWORD = &HFFFF
Public Const INVALID_HANDLE_VALUE = -1
Public Const FILE_ATTRIBUTE_ARCHIVE = &H20
Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
Public Const FILE_ATTRIBUTE_HIDDEN = &H2
Public Const FILE_ATTRIBUTE_NORMAL = &H80
Public Const FILE_ATTRIBUTE_READONLY = &H1
Public Const FILE_ATTRIBUTE_SYSTEM = &H4
Public Const FILE_ATTRIBUTE_TEMPORARY = &H100            

Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type            

Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type            

Public Function StripNulls(OriginalStr As String) As String

If (InStr(OriginalStr, Chr(0)) > 0) Then
    OriginalStr = Left(OriginalStr, _
    InStr(OriginalStr, Chr(0)) - 1)
End If            

StripNulls = OriginalStr

End Function

4. Copy the following code into Form1's module:

Option Explicit

Function FindFilesAPI(path As String, SearchStr As String, _
FileCount As Integer, DirCount As Integer)            

Dim FileName As String ' Walking filename variable...
Dim DirName As String ' SubDirectory Name
Dim dirNames() As String ' Buffer for directory name entries
Dim nDir As Integer ' Number of directories in this path
Dim i As Integer ' For-loop counter...
Dim hSearch As Long ' Search Handle
Dim WFD As WIN32_FIND_DATA
Dim Cont As Integer            

If Right(path, 1) <> "\" Then path = path & "\"

' Search for subdirectories.
nDir = 0
ReDim dirNames(nDir)
Cont = True
hSearch = FindFirstFile(path & "*", WFD)
If hSearch <> INVALID_HANDLE_VALUE Then
    Do While Cont
    DirName = StripNulls(WFD.cFileName)
    ' Ignore the current and encompassing directories.
    If (DirName <> ".") And (DirName <> "..") Then
        ' Check for directory with bitwise comparison.
        If GetFileAttributes(path & DirName) And _
        FILE_ATTRIBUTE_DIRECTORY Then
            dirNames(nDir) = DirName
            DirCount = DirCount + 1
            nDir = nDir + 1
            ReDim Preserve dirNames(nDir)
        End If
    End If
    Cont = FindNextFile(hSearch, WFD) 'Get next subdirectory.
    Loop
    Cont = FindClose(hSearch)
End If            

' Walk through this directory and sum file sizes.

hSearch = FindFirstFile(path & SearchStr, WFD)
Cont = True            

If hSearch <> INVALID_HANDLE_VALUE Then
    While Cont
    FileName = StripNulls(WFD.cFileName)
    If (FileName <> ".") And (FileName <> "..") Then
        FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * _
        MAXDWORD) + WFD.nFileSizeLow
        FileCount = FileCount + 1
        List1.AddItem path & FileName
    End If
    Cont = FindNextFile(hSearch, WFD) ' Get next file
    Wend
    Cont = FindClose(hSearch)
End If            

' If there are sub-directories...

If nDir > 0 Then
    ' Recursively walk into them...
    For i = 0 To nDir - 1
    FindFilesAPI = FindFilesAPI + FindFilesAPI(path & _
    dirNames(i) & "\", SearchStr, FileCount, DirCount)
    Next i
End If            

End Function

Private Sub Command1_Click()

Dim SearchPath As String, FindStr As String
Dim FileSize As Long
Dim NumFiles As Integer, NumDirs As Integer
Screen.MousePointer = vbHourglass
List1.Clear
SearchPath = Text1.Text
FindStr = Text2.Text
FileSize = FindFilesAPI(SearchPath, FindStr, NumFiles, NumDirs)
Text3.Text = NumFiles & " Files found in " & NumDirs + 1 & _
" Directories"
Text4.Text = "Size of files found under " & SearchPath & " = " & _            

Format(FileSize, "#,###,###,##0") & " Bytes"
Screen.MousePointer = vbDefault
End Sub            

5. Run the Project. Enter a starting path into Text1, a search string in Text2 (like *.* or *.txt) and then click Command1.

You see a list of the files found appear in the list box, the actual number of files found displays in Text3, and the total size of the files found under the starting directory appears in Text4.

 

 


Copyright © 1998-2007, The Mentalis.org Team - Privacy statement
Did you find a bug on this page? Tell us!
This site is located at http://allapi.mentalis.org/