SearchPath


Another common file task is to find out where a file is located, if anywhere, in a path list (usually the one in the PATH environment variable). Most language libraries provide a function for this purpose. Microsoft Visual C++, for example, has _searchenv. Visual Basic has zip. Actually, you could do this task in Basic. It’s simply a matter of getting the directory list with Environ$, parsing off each directory, appending the filename, and checking to see whether the file exists. But that’s a lot of work that the operating system already knows how to do.


Win32 provides the mother of all path-searching functions: SearchPath. Some of its many features, like those of GetFullPathName, don’t work well for Basic. The previous edition of this book provided a SearchDirs function that attempted to solve these problems. It was modeled closely on the SearchPath function. You could call it like this:

sFullName = SearchDirs(sEmpty, “calc.exe”, sEmpty, iDir, iBase, iExt)

The function would return the full path in the return value and the indexes of the directory, base file, and extension through reference variables. The first and third arguments were for the path to search and for the extension, but in most cases you would just pass an empty string (the sEmpty constant from my type library). You could use the returned indexes with the Mid$ function to extract the parts of the full path. This was nice, but you always had to declare and pass those index variables whether you wanted them or not, and you always had to pass empty variables for the path and extension.


The new SearchDirs function takes optional arguments for five of its six parameters. The original SearchDirs tried to maintain a parameter order similar to that of SearchPath, but SearchDirs orders the arguments logically in order to make it easier to leave off ones that usually aren’t needed. Any of the following Basic statements are OK:

sFullName = SearchDirs(“calc”, “.exe”, , iBase, iExt, iDir)
sFullName = SearchDirs(“calc.exe”, , , iBase, iExt)
sFullName = SearchDirs(“calc”, “.exe”, Environ(“PATH”), iBase)
sFullName = SearchDirs(“calc.exe”)

That’s a lot of parameters, so let’s step through them. The first parameter is the file to be found. The filename is first because it is required and is often the only argument needed. It can include the extension, or the extension can be given in the second parameter. The third parameter is the path to be searched. No argument signals a search of the default Windows search path. The remaining arguments hold the variables in which the function can return the name, extension, and directory positions—in the same order as GetFullPath.


If you leave the third argument blank (as you usually will), SearchDirs looks for files in the following order:
  1. the executable directory

  2. the current directory

  3. the Windows system directory

  4. the Windows directory

  5. the directory list in the PATH environment variable

When using SearchDirs, consider this order carefully. You might not always find what you expect to find where you expect to find it.


SearchDirs has other uses. It can search a different path list in an environment variable:

sFullName = SearchDirs(“WINDOWS.H”, , Environ(“INCLUDE”))

It can test for the existence of a file in the current directory:

sFullName = SearchDirs(“DEBUG.BAS”, , “.”)

That statement looks a lot like this one:

sFullName = GetFullPath(“DEBUG.BAS”)

But there’s a subtle difference. GetFullPath gives a valid filename whether or not the file exists. You can use it to get the full pathname of a file you’re about to create. SearchDirs confirms that a file with that name already exists.


You can also use SearchDirs to search for a file when you’re not sure of the extension:

sName = “EDIT”
Dim asExts(1 To 4) As String
asExts(1) = “.EXE”: asExts(2) = “.COM”
asExts(3) = “.BAT”: asExts(4) = “.PIF”
For i = 1 To 4
sFullName = SearchDirs(sName, asExts(i))
If sFullName <> sEmpty Then Exit For
Next

This is why SearchDirs (and SearchPath) has a separate parameter for the
extension.