Web Binary Download Methods
Here is the "usual" method of performing a binary download over HTTP.
It tries four different binary download capable objects, and has two
separate methods for saving the binary to disk. Fairly bulletproof:
Function SaveWebBinary(strUrl, strFile) 'As Boolean
Const adTypeBinary = 1
Const adSaveCreateOverWrite = 2
Const ForWriting = 2
Dim web, varByteArray, strData, strBuffer, lngCounter, ado
On Error Resume Next
'Download the file with any available object
Err.Clear
Set web = Nothing
Set web = CreateObject("WinHttp.WinHttpRequest.5.1")
If web Is Nothing Then Set web = CreateObject("WinHttp.WinHttpRequest")
If web Is Nothing Then Set web = CreateObject("MSXML2.ServerXMLHTTP")
If web Is Nothing Then Set web = CreateObject("Microsoft.XMLHTTP")
web.Open "GET", strURL, False
web.Send
If Err.Number <> 0 Then
SaveWebBinary = False
Set web = Nothing
Exit Function
End If
If web.Status <> "200" Then
SaveWebBinary = False
Set web = Nothing
Exit Function
End If
varByteArray = web.ResponseBody
Set web = Nothing
'Now save the file with any available method
On Error Resume Next
Set ado = Nothing
Set ado = CreateObject("ADODB.Stream")
If ado Is Nothing Then
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(strFile, ForWriting, True)
strData = ""
strBuffer = ""
For lngCounter = 0 to UBound(varByteArray)
ts.Write Chr(255 And Ascb(Midb(varByteArray,lngCounter + 1, 1)))
Next
ts.Close
Else
ado.Type = adTypeBinary
ado.Open
ado.Write varByteArray
ado.SaveToFile strFile, adSaveCreateOverWrite
ado.Close
End If
SaveWebBinary = True
End Function
I was playing around and found other ways you can
misuse the system
to do a binary download!
WSC file:
You don't have to register WSC files. Instead, you can specify their
location in your script. You can even specify an HTTP location. The
file is downloaded automatically and ends up in your IE cache. If you
specify something other than a real WSC file as the target, it gets
downloaded and run as a script. Which is gonna throw an error! So you
just block the error:
On Error Resume Next
GetObject "script:http://www.ericphelps.com/image/logo1.gif"
The code above is ordinary VBS code. Nothing to do with WSC files
except that the "GetObject" method with the "script:" protocol is
NORMALLY used to get a WSC file. We use it here to get something else.
The above VBS code will download a graphic from my web page and drop it
in the IE cache. To locate the file in the cache, use code similar to
this:
Function FindInCache(strFile)
'Supply a file name only (no path) and it will return the
'full path and file to the file's first located cache location.
'If the file is not found, an empty string will be returned.
Dim wsh, fso, strFileName, strFilePath
strFileName = strFile
Set fso = CreateObject("Scripting.FileSystemObject")
Set wsh = CreateObject("Wscript.Shell")
'Cache files generally have "[1]" inserted just before the file extension.
If InStr(strFileName, "].") = 0 Then
strFileName = Left(strFileName, InStrRev(strFileName, ".") - 1) & "[1]" & Mid(strFileName, InStrRev(strFileName, "."))
End If
'Start building the file path by getting the basic path
strFilePath = wsh.Environment("PROCESS")("USERPROFILE")
strFilePath = strFilePath & "\Local Settings\Temporary Internet Files\"
'Now search the possible paths for the desired file
strFilePath = SearchForFile(fso.GetFolder(strFilePath), strFileName)
'Return the result
FindInCache = strFilePath
End Sub
Function SearchForFile(objFolder, strFile)
Dim fils, fil, fols, fol, strFilePath
'Check all the files in the current folder
On Error Resume Next
Set fils = objFolder.Files
If Err.Number = 0 Then
For Each fil In fils
If fil.Name = strFile Then
SearchForFile = fil.Path
Exit Function
End If
Next
End If
'Check for any sub folders and recursively search them
Set fols = objFolder.SubFolders
For each fol in fols
strFilePath = ""
strFilePath = SearchForFile(fol, strFile)
If strFilePath <> "" Then
SearchForFile = strFilePath
Exit Function
End If
Next
SearchForFile = strFilePath
End Function
In real life, you'd want to search the cache FIRST, delete any matches
you found, then download the file you wanted. Then whatever you find in
the cache is sure to be what you want.
WSF file:
If you write your VBS code in WSH files instead of in VBS files, you
get to specify a lot more options. Including where to get external code:
<job>
<script language="vbscript"
src="http://www.ericphelps.com/image/logo1.gif"/>
</job>
Unfortunately, this crashes the entire WSF file, so you need to have
your VBS file create or use a WSF file like the one above and run it
with wsh.Run or wsh.Exec so your mainline code will survive. Try
something like this VBS code:
Dim wsh, fso, ts
Const TEMP_FILE = "C:\~temp.wsf"
Set wsh = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(TEMP_FILE, 2, True)
ts.WriteLine "<job>"
ts.WriteLine "<script language=""vbscript"" "
ts.WriteLine "src=""http://www.ericphelps.com/image/logo1.gif""/>"
ts.WriteLine "</job>"
ts.Close
wsh.Run "cscript.exe " & TEMP_FILE, 0, True
fso.DeleteFile TEMP_FILE
It's important that the wsh.Run happen with CSCRIPT.EXE as the running
engine and that it run with zero as the window type. When the WSF file
throws it's error, if the engine was wscript, it would pop up an error
dialog. That's bad. By using the cscript engine, the error just gets
written in the DOS box. And by setting the window type to zero, nobody
even sees the DOS box. And sure enough, the file "logo1.gif" would
appear in your IE cache.
Again, once the file is in you cache, use code similar to the
"FindInCache" and "SearchForFile" functions I showed above to mentioned
above to locate your file.