Build an ASP Site Search Facility with VBScript and the FileSystem Object

By Peter A. Bromberg, Ph.D.

Peter Bromberg

 

A lot of developers have sites that need some kind of search facility, but they either don't have access to the MS Indexing Service (Index Server for you NT4.0 folks) or for whatever reason, it may not be feasible to install it or have it running.

Fear Not! It's really easy to produce a professional - looking "Homebrew" search facility, and unless your site is extremely large, you may be pleasantly surprised at how fast it can be. All we need to do is use the built- in Scripting.FileSystem object and its methods to iterate through a specified folder and it's subfolders, examining the content of each file for the requested search term, and then populate a list of regular HTML <A HREF... links with the results.

This can all be implemented in a single ASP page, so let's get "under the hood", so to speak and look at some code.



First, we need to tell if our search form has been "autoposted", so we write:

<%
' NOINDEX
option Explicit
Dim objFolder,strSearchText,objfso,sc,numItems,begpos,endpos,slen,sResult
if Request.form("SearchText") = "" Then
With Response
.write "<head></head><BODY ><Basefont face="tahoma"><TITLE>Search www.mysite.com</TITLE><h2><Center>Search www.mysite.com </h2></center><BR><div align="center" id=status></div><BR><BR>"
.write "<FORM ACTION=Search.asp METHOD=POST>"
.write "<INPUT TYPE=TEXT NAME=SearchText>Search Term<BR>"
'.write "<INPUT TYPE=TEXT NAME=SC VALUE=.>SCOPE (. or /)<BR>"
' Disabled above line to keep scope in current folder and subfolders
.write "<INPUT TYPE=SUBMIT VALUE=FIND></FORM>"
end with
else

Note here that we check to see if the Request.Form collection holds a value in the "SearchText" member from a form post, and if it does not , we Response.write out our search form to the user. The comment with 'NOINDEX is used to tell the script to ignore certain pages that we don't want to come up in a search, I'll get to that in a moment.

Assuming that our user has filled in a search term on the form and posted it, we come to the code after the "else" in our "if- then - else" block:

' Set the Script timeout to a high enough number to let the search finish
Server.ScriptTimeout = 90
' Grab the search term from the form post and convert all to upper case
strSearchText = UCase(Request.Form("SearchText") )
' Create the FSO and Folder objects
Set objfso = Server.CreateObject("Scripting.FileSystemObject")
' Create a "scope" term that can be used to set the scope of the search root folder
sc = Request.form("SC")
' comment out next line to enable SEARCH SCOPE (e.g. "."=curdir, "/"=full site , "../"=one directory up, etc.)
sc ="."
' Set the starting folder to the specified directory
Set objFolder = objFSO.GetFolder(Server.MapPath(sc))
sResult ="<head></head><BODY ><TITLE>Search Results</TITLE><h2><Center>Search in Articles</h2></center><BR><div align="center" id=status></div><BR><BR>"
' Call the Search function
Search objFolder
if numItems = "" then numItems = "0"
' Create a nice client-side DHTML status <div> with search result info
sResult =sResult & "<BR><script language=Javascript>document.all.status.innerHTML="""&numItems&" Files Found. <BR> <A href=search.asp>Search Again</a>"";</script></body></html>"
Response.write sResult
' Now here's the Search function ...
Function Search(objFolder)
Dim objSubFolder,sext,objFile,objTextStream,strFileContents
on error resume next
' Iterate through each file in this folder ...
For Each objFile in objFolder.Files
' Get the file extension -- to upper case for comparison (Actually there's a GetExtensionName builtin method, but let's keep it simple)
sext = Ucase(mid(objFile.Name, Len(objFile.Name)-3, 4))
' You decide here what file extensions you want to be searched ...
'if sext = ".HTM" or sext = ".TXT" or sext = ".ASP" then
if sext = ".ASP" then
' OK now we gotta actually read in the file contents so we can look for search term...
Set objTextStream = objFSO.OpenTextFile(objFile.Path,1)
strFileContents = objTextStream.ReadAll
strFileContents = UCase(strFileContents)
' AHA! if i put in "NOINDEX" in my private file, it doesn't come up in the list ...
if instr(1,strFileContents, "NOINDEX",1) = 0 then ' skip files with robots "noindex"
' OK now we look for our search term..
If InStr(1, strFileContents, strSearchText, 1) then
' We found it - increment our numItems counter, and create a hyperlink for the file ...
numItems = numItems +1
sResult = sResult & numItems & ".)&nbsp; <A HREF=""" & objFile.Name & """>" & objFile.Name & "</A><BR>"
End if
End If
' Close out TextStream object
objTextStream.Close
end if
' Did we get any errors?
if err.number <> 0 then
response.write err.description & "<BR>"
err.clear
end if
' Ok, let's check the next file in this folder ...
Next
'Here we recurse - for each subfolder in this directory, run the Search function again
For Each objSubFolder in objFolder.SubFolders
Search objSubFolder
Next
End Function
end if
' And friends, that's all there is to it - Instant File Search capability for your site!
%>

I am sure you can come up with plenty of enhancements to this basic concept! Enjoy.

Peter Bromberg is an independent consultant specializing in distributed .NET solutionsan independent consultant specializing in distributed application development in Orlando and a co-developer of the NullSkull.com developer website. He can be reached at info@eggheadcafe.com