ASP 101 - Active Server Pages 101 - Web04
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
The Top 10 ASP Links @ Microsoft.com
What is Adovbs.inc and Why Do I Need It?
An Overview of ASP.NET

QUICK TIP:
Make Sure Colors Exist
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


Searching Drives, Viewing and Downloading Files

by Jason Withrow

Does your knowledge of the FileSystem Object need some refreshing?

Here is a handy little example of how to use what and where. It could also serve some administration functions as well. In fact, I find it very useful. My office has very tight security rules, one of which is that all FTP ports are shut off. Which means that if I am at work, I can't get anything off my home PC, unless it is inside of an IIS virtual directory. Well, not anymore! I just connect to my home web server, pull up the folder list page, and I have instant access to any file on my home computer.

It will allow you to choose the drive to search, and then it will build a listbox of all the folder paths on that drive.

Choose the Folder Path and it will build a listbox of all the files in that folder.

Choose a File and, if it is a text file type, will display the contents in the browser, if it is a binary file, it will prompt you to save the file to your hard drive.

Save As... Dialog Box Screen Shot

This can come in handy for server maintenance, since it will allow you to view and download Files/Folders that are not web enabled (outside a virtual directory).

To handle the download, I have a small DLL that will read the binary data of the file and send it back as a binary stream via the ASP Response.BinaryWrite Function.

You can still use this example without the DLL; you will just lose the Save to Disk Method. The Compiled DLL is also included, so you can just register it on your server if you don't want to make it yourself.

Here is the Source for the DLL. It was taken from MSDN: http://support.microsoft.com/support/kb/articles/Q193/9/98.ASP

  1. Create a new ActiveX DLL project in Visual Basic 5.0 or later.
  2. Rename the project FileSave.
  3. Rename the class module BinRead.
  4. Cut and paste the following code into the General Declarations section of the class module:
    Function readBinFile(ByVal bfilename As String) As Variant
        Dim fl As Long
        Dim FileNum As Long
        Dim binbyte() As Byte
        Dim binfilestr As String
        On Error GoTo errHandler
        FileNum = FreeFile
        Open bfilename For Binary Access Read As #FileNum
        fl = FileLen(bfilename)
        ReDim binbyte(fl)
        Get #FileNum, , binbyte
        Close #FileNum
        readBinFile = binbyte
        Exit Function
      errHandler:
        Exit Function
    End Function
    
  5. Save the project.
  6. On the File menu click Make FileSave.dll.

All set, then let's start coding.

First we want to set up at least some level of security, I recommend using NT permissions on this file, but let's at least setup some simple asp based authentication. The following code will redirect to ASP 101 if the client has not supplied the correct username in the query string (www.mysite.com/newFolders.asp?user=me)

<%
Session("user") = Request.QueryString("user")
IF Session("user") <> "me" Then
    Response.Redirect("http://www.asp101.com/")
End IF
%>

Now let's start building our file access methods. We are going to wrap them in a class, so that we may reuse expensive objects using a custom property.

Class clsIterate
Private m_oFS
Public Property Let oFS(objOFS) 'Property to Hold oFS Pointer
    m_oFS = objOFS
End Property
Public Property Get oFS()
    Set oFS = Server.CreateObject("Scripting.FileSystemObject")
End Property

Let's add some time saving routines for cleaning up objects and using Response.Write

Function Echo(str)
    Echo = Response.Write(str & vbCrLf)
End Function
Function EchoB(str)
    EchoB = Response.Write(str & "<BR>" & vbCrLf)
End Function
Sub Cleanup(obj)
    If isObject(obj) Then
        Set obj = Nothing
    End IF
End Sub

Next we need to set up our routine to build the drives list box. Since I don't know what drives you may have; or how many, we will loop thru all the drives on the computer, checking to see if they are available, if so, we will add it to our listbox.

Sub BuildDriveList(strDrive)
    Set oDrives = oFS.Drives
    EchoB("<B>Select Drive</B>")
    Echo("<SELECT NAME=frmDrives>")
    For Each DrivePath in oDrives
        If DrivePath.isReady Then
            IF strDrive = DrivePath.DriveLetter Then
                strSelected = " SELECTED"
            Else
                strSelected = Null
            End IF
            Echo("<OPTION VALUE=" & Chr(34) & DrivePath.DriveLetter _
              & Chr(34) & strSelected & ">" &  DrivePath.DriveLetter _
              & "</OPTION>")
        End IF
    Next
    EchoB("</SELECT>")
    Cleanup oDrives
End Sub

Now that we have a listbox containing all the available drives, we need a routine that will iterate all the directories on that drive. Word of warning in advance, the more folders on the drive, the longer this routine will take to complete when run. This Sub will take 2 parameters, the parent Folder (in our case, a drive object) of the directory to start at and the current path (if any), to bookmark our place in the listbox.

Sub BuildFolderList(objParentFolder, strCurrentPath)
Dim objFolder, objSubFolder, objFile
'Create a subfolder Object for the current Parent Folder
Set objSubFolder = objParentFolder.SubFolders
'Some WILL Throw Permission Denied Errors -Just Skip Em
On Error Resume Next
'Loop thru each Folder in the Parent's Subfolders
For Each objFolder In objSubFolder
'Insert  SELECTED into the Option list to save our place.
IF strCurrentPath = objFolder.Path Then
        strSelected = " SELECTED"
    Else
        strSelected = Null
    End IF
      Echo("<OPTION STYLE=" & Chr(34) & "font-size: 10px" & Chr(34) _
        & " VALUE=" & Chr(34) & objFolder.Path & Chr(34) _
        & strSelected & ">" & objFolder.Path & "</OPTION>")
      'Recursive Call To Iterate Entire Drive
      BuildFolderList objFolder, strCurrentPath
Next
    Cleanup objSubFolder
    Cleanup objParentFolder
End Sub

Let's do the same thing as above, but for a FileList this time.

Sub BuildFileList(strFolder)
    'We Know it Exists so Just Get it
    Set oFolder = oFS.getFolder(strFolder)
    EchoB("<B>Select File</B>")
    Echo("<SELECT NAME=frmFiles>")
    For Each FileName in oFolder.Files
        Echo("<OPTION  STYLE=" & Chr(34) & "font-size: 10px" _
        & Chr(34) & " VALUE=" & Chr(34) & FileName.Path _
        & Chr(34) & ">" & FileName.Path & "</OPTION>")
    Next
    EchoB("</SELECT>")
    Cleanup oFolder
End Sub    

Next is a simple Select case statement to determine if we are viewing a text based file type or not. Feel free to add your own here, as I am sure I missed a few.

Function FileType(strFile)
    strExt = lcase(Right(strFile, 4))
        Select Case strExt
            Case ".txt"
                FileType = "Text"
            Case ".inf"
                FileType = "Text"
            Case ".asp"
                FileType = "Text"
            Case ".htm"
                FileType = "Text"
            Case ".vbs"
                FileType = "Text"
            Case ".log"
                FileType = "Text"
            Case ".vbp"
                FileType = "Text"
            Case ".cls"
                FileType = "Text"
            Case ".dsw"
                FileType = "Text"
            Case ".inc"
                FileType = "Text"
            Case ".dsp"
                FileType = "Text"
            Case ".ini"
                FileType = "Text"
            Case Else
                FileType = "Binary"
        End Select
    End Function

Here comes my favorite part! This next function will add the appropriate headers for a binary file, as well as the correct file size (so the download progress bar works correctly), and force a 'Save File' dialogue box in Internet Explorer by setting the Content-Disposition to attachment and writing the file as a binary stream (Passed back from our fileSave.dll). For more information on forcing downloads and using Content-Disposition see RFC 2183.

Sub AddHeaders(strFilePath)
    strFileType = lcase(Right(strFile, 4))
    Set oFile = oFS.GetFile(strFilePath)
    Select Case strFileType
        Case ".asf"
            ContentType = "video/x-ms-asf"
        Case ".avi"
            ContentType = "video/avi"
        Case ".doc"
            ContentType = "application/msword"
        Case ".zip"
            ContentType = "application/zip"
        Case ".xls"
            ContentType = "application/vnd.ms-excel"
        Case ".gif"
            ContentType = "image/gif"
        Case ".jpg", "jpeg"
            ContentType = "image/jpeg"
        Case ".wav"
            ContentType = "audio/wav"
        Case ".mp3"
            ContentType = "audio/mpeg3"
        Case ".mpg", "mpeg"
            ContentType = "video/mpeg"
        Case ".rtf"
            ContentType = "application/rtf"
        Case Else
            'Handle All Other NON-Text Files
            ContentType = "application/octet-stream"
    End Select
    '********************************************************
    ' NOTE: PRE IE 5.5 SP1 has a Bug that will display known 
    ' file types in the Browser Thus ignoring the attachment
    ' disposition.  The Simple object I am using alleviates
    ' this problem on Pre IE 5.5 Browsers
    '********************************************************
    'Clear Response Collection So BinaryWrite Can Complete
    Response.Clear
    Response.AddHeader "Content-Disposition", _
        "attachment; filename=" & oFile.name
    'Specify size so that the browser's progress bar works properly
    Response.AddHeader "Content-Length", oFile.size
    Response.ContentType = ContentType
    'Read Binary Bytes
    Set oSave = Server.CreateObject("FileSave.binRead") 
       'Get Binary data from the DLL
       vntStream = oSave.readBinFile(strFilePath)
       'Force Save Dialogue in Browser
       Response.BinaryWrite(vntStream)
    Cleanup strFile
    cleanup oFile
End Sub
End Class

All that's left to do now is to call our routines from inside the BODY of our asp page. Here is the code.

Dim frmDrives, frmFolders, frmFiles
frmDrive = Request.Form("frmDrives")
frmFolder = Request.Form("frmFolders")
frmFile = Request.Form("frmFiles")
Set Iterate = New clsIterate
    Call Iterate.BuildDriveList(frmDrive)
    IF frmDrive <> "" Then
        Set objFS = Server.CreateObject("Scripting.FileSystemObject")
        Set oDrive = objFS.GetDrive(frmDrive)
        Set oRootDir = oDrive.RootFolder
        Iterate.EchoB("<B>Select Folder</B>")
        Iterate.Echo("<SELECT NAME=frmFolders STYLE=" & Chr(34) _
            & "font-size: 10px" & Chr(34) & ">")
        'Used To Change Drives
        Iterate.Echo("<OPTION VALUE="""">- None -</OPTION>")
        Call Iterate.BuildFolderList(oRootDir, frmFolder)
        Iterate.EchoB("</SELECT>")
    End IF
    IF frmFolder <> "" Then
        'Build Options
        Call Iterate.BuildFileList(frmFolder)
    End IF
    Iterate.Echo("<INPUT TYPE=" & Chr(34) & "SUBMIT" & Chr(34) _
        & " VALUE=" & Chr(34) & "Go Get It" & Chr(34) & ">")
    Iterate.Echo("</TD>")
    Iterate.Echo("</TR><TR><TD VALIGN=TOP CLASS=dispSource>")
    IF frmFile <> "" Then
    Iterate.EchoB(Iterate.FileType(frmFile))
        IF Iterate.FileType(frmFile) = "Text" Then
            Set oText = objFS.OpenTextFile(frmFile, 1, True)
            Do While Not oText.AtEndOfStream
                Data = Server.HTMLEncode(Trim(oText.Readline))
                tempData = tempData & Data & "<BR>"
            Loop
            Iterate.Echo(tempData)
        Else
            Iterate.AddHeaders frmFile
        End IF
    End IF
    Set oText = Nothing
    Iterate.Cleanup oDrive
    Iterate.Cleanup oRootDir
    Iterate.Cleanup objFS
Set Iterate = Nothing

That's it, you can now get any file off your home or office computer from anywhere with an Internet connection.


Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback

Internet.com
The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers