26

Ive got a VBS Script that,generates an url to download a file from a server on my network. I now need to download the file to "C:\rWallpaper\wallpaper.png", the URL is stored in the variable "url".

Id like it to work something like wget on linux, just download and save the file to a specified location.

Arcath
  • 4,331
  • 9
  • 39
  • 71

6 Answers6

48

You can download using XMLHTTP and leverage an ADO stream to write the binary data;

dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", "http://example.com/someimage.png", False
xHttp.Send

with bStrm
    .type = 1 '//binary
    .open
    .write xHttp.responseBody
    .savetofile "c:\temp\someimage.png", 2 '//overwrite
end with
bw_üezi
  • 4,483
  • 4
  • 23
  • 41
Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • This works and helped me a lot, but you have to specify target name. Problem is if you want to use the original filename that was suggested by server. – Racky Mar 14 '13 at 15:19
  • 8
    @Racky after `.send` (should the server deem to do so) the suggested file name is after the `filename=`token available via `hdr = xHttp.getResponseHeader("Content-Disposition")` – Alex K. Mar 14 '13 at 15:30
  • Thanks works well - I just wrapped it into a function and badabing badaboom – Derrick Dennis May 23 '18 at 03:46
  • At last! This code works with both `http` and `https`, side to side with the 3 other "solutions" I already checked in stackoverflow that didn't work with `https`. You deserve a medal! :) – Apostolos Nov 11 '18 at 09:40
  • The user needs to the option of deciding where to save to. Otherwise they will not know it was successfully downloaded, or where to find it. – WilliamK Jul 15 '22 at 23:31
8

The above answer threw the error Write to file failed. Code: 800A0BBC for me, however this worked:

HTTPDownload "http://www.emagcloud.com/europeansealing/FSA_ESA_Compression_Packing_Technical_Manual_v3/pubData/source/images/pages/page10.jpg", "C:\"

Where

Sub HTTPDownload( myURL, myPath )
    ' This Sub downloads the FILE specified in myURL to the path specified in myPath.
    '
    ' myURL must always end with a file name
    ' myPath may be a directory or a file name; in either case the directory must exist
    '
    ' Written by Rob van der Woude
    ' http://www.robvanderwoude.com
    '
    ' Based on a script found on the Thai Visa forum
    ' http://www.thaivisa.com/forum/index.php?showtopic=21832
    
        ' Standard housekeeping
        Dim i, objFile, objFSO, objHTTP, strFile, strMsg
        Const ForReading = 1, ForWriting = 2, ForAppending = 8
    
        ' Create a File System Object
        Set objFSO = CreateObject( "Scripting.FileSystemObject" )
    
        ' Check if the specified target file or folder exists,
        ' and build the fully qualified path of the target file
        If objFSO.FolderExists( myPath ) Then
            strFile = objFSO.BuildPath( myPath, Mid( myURL, InStrRev( myURL, "/" ) + 1 ) )
        ElseIf objFSO.FolderExists( Left( myPath, InStrRev( myPath, "\" ) - 1 ) ) Then
            strFile = myPath
        Else
            WScript.Echo "ERROR: Target folder not found."
            Exit Sub
        End If
    
        ' Create or open the target file
        Set objFile = objFSO.OpenTextFile( strFile, ForWriting, True )
    
        ' Create an HTTP object
        Set objHTTP = CreateObject( "WinHttp.WinHttpRequest.5.1" )
    
        ' Download the specified URL
        objHTTP.Open "GET", myURL, False
        objHTTP.Send
    
        ' Write the downloaded byte stream to the target file
        For i = 1 To LenB( objHTTP.ResponseBody )
            objFile.Write Chr( AscB( MidB( objHTTP.ResponseBody, i, 1 ) ) )
        Next
    
        ' Close the target file
        objFile.Close( )
End Sub
Charles Clayton
  • 17,005
  • 11
  • 87
  • 120
  • If the accepted answer failed with that specific error the issue is permissions to write to the folder, which is not difficult to solve. – user692942 Feb 09 '17 at 09:24
  • 1
    You're right, and I solved it by using the provided code. – Charles Clayton Feb 09 '17 at 15:49
  • 3
    Your method is very slow when the file size is large (e.g. a 400k pdf , i used 20 secs to download) the marked answer which only uses 2 secs to download the same file. – Vin.X Jun 06 '17 at 01:32
  • I'm trying this to download a png file. It creates the new file, but the png file is either incomplete or something else - it has no image. – bgmCoder Jan 09 '20 at 21:36
6

In addition to Alex K answer, I used the following if it helps someone :

Define object

Set objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")

Call Download link with a file ( image in our case )

URL = "https://www.grupya.com/public/assets/img/logo.png"
objWinHttp.open "GET", URL, False
objWinHttp.send ""

Save the Binary data to Disk

SaveBinaryData "c:\temp\my.png",objWinHttp.responseBody

SaveBinaryData Function

Function SaveBinaryData(FileName, Data)

' adTypeText for binary = 1
Const adTypeText = 1
Const adSaveCreateOverWrite = 2

' Create Stream object
Dim BinaryStream
Set BinaryStream = CreateObject("ADODB.Stream")

' Specify stream type - we want To save Data/string data.
BinaryStream.Type = adTypeText

' Open the stream And write binary data To the object
BinaryStream.Open
BinaryStream.Write Data

' Save binary data To disk
BinaryStream.SaveToFile FileName, adSaveCreateOverWrite

End Function
1

I found out that mapping a drive can be a good approach

   dim Z
   Z = "http:// .... " '(base url)
   Set FSO = CreateObject("Scripting.Filesystemobject")
    Set objNetwork = CreateObject("WScript.Network") 
    '## This is for network drives
    
    If FSO.driveExists ("Z:") then 
        objNetwork.RemoveNetworkDrive "Z:", True, True
    End If      

    '## for adding
    'Set objNetwork = CreateObject("WScript.Network")
    objNetwork.MapNetworkDrive "Z:" , Z

From there, you can define the rest of the url to your file

SourceFileName = "Z:\" & ...

and a destination File Name

DestinFileName = "..."

Then you can use

 FSO.CopyFile SourceFileName, DestinFileName, True
FRanck
  • 11
  • 2
  • Interesting, thanks. I guess this works only if the remote HTTP service has WebDAV extensions enabled: https://social.technet.microsoft.com/Forums/lync/en-US/ea5a16b8-f6ae-48fc-8f0f-f5e8957d7b16/map-http-drive – saulius2 Jun 01 '23 at 04:33
0

This post is old, but the error in the first code answer is that you need privileges to write at C:\,Try at desktop or %temp%, it works.

Manuel
  • 31
  • 2
-1

Try:

CreateObject("WScript.Shell").Run "curl -o "Path and filename"
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
  • 3
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – 31piy Aug 17 '18 at 04:44
  • 2
    This would require curl be installed on the target machine which isn't true of most windows machines. – Arcath Aug 19 '18 at 19:44