Author Topic: DownloadWithProgress  (Read 89 times)

airr

  • Full Member
  • ***
  • Posts: 125
    • View Profile
DownloadWithProgress
« on: April 17, 2024, 11:07:44 AM »
For a CLI tool I'm working on I needed a way to download a file and show progress.

Using UrlDownloadToFile with a callback is a convoluted mess and I gave up on that approach. Plus you need to use COM for it to work.

Anyway, I rolled my own which turned out to be fairly easy,

Code: [Select]
Dim Source$

$pragma comment(lib, "wininet.lib")

' ~629MB Test  File, Debian ISO
Source$ = "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso"


DownloadWithProgress(Source$)

Pause


Sub DownloadWithProgress(url$)
    Dim As HINTERNET hInternet, hUrl
    Dim szSize$, filename$, Dest$[20]
    Dim As DWORD dwBytesRead, dwPercentage
    Dim bRead as BOOL, bufferSize, contentSize, cnt
    dim pBuffer[BCXSTRSIZE] as Byte

    cnt = Split(Dest$,url$,"/")
    filename$ = Dest$[cnt-1]

    hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0)
    if hInternet = Null then print "InternetOpen Failed", GetLastError(): End = 1

    hUrl = InternetOpenUrl(hInternet, url$, NULL, 0, INTERNET_FLAG_RELOAD, 0)
    if hUrl = Null then
        print "InternetOpenUrl Failed", GetLastError()
        InternetCloseHandle(hInternet)
        End = 1
    End If
   
    contentSize = getContentSize(hUrl)
   
    OPEN filename$ FOR Binary New AS FP1
   
    Color 11,0 : Print E"\n Downloading ", filename$,"...\n" : Color 7,0
   
    While True
        bRead = InternetReadFile( hUrl, pBuffer, sizeof(pBuffer), &dwBytesRead)

        If dwBytesRead = 0 then Exit While

        If Not bRead Then
            Print "InternetReadFile error : ", GetLastError()
            Close FP1 : CloseConnections(2,hUrl,hInternet)
            End = 1
        End If

        bufferSize += dwBytesRead
       
        dwPercentage = Round((double)bufferSize / contentSize * 100,0)
   
        szSize$ = convertFromBytes(bufferSize)
       
        Color 14,0
        Print E"\r", dwPercentage, "% [", rpad$(repeat$(dwPercentage / 2, chr$(177)), 50),"]",bufferSize / 1048576, szSize$, " of", contentSize / 1048576, "MB  ";
        Color 7,0
       
        put$ FP1, pBuffer, sizeof(pBuffer)
    Wend 
     
    Close FP1
    CloseConnections(2,hUrl,hInternet)
   
End Sub

Sub CloseConnections(i%,...)
    Dim As HINTERNET handle
    Dim As va_list ap

    va_start(ap, i%)

    For integer cnt = 0 To i% -1
        handle = va_arg(ap,HINTERNET)
        InternetCloseHandle(handle)
    Next

    va_end(ap)
End Sub

Function convertFromBytes(bufSize%) As String
    Dim szSize$
    Select Case bufSize%
        Case < 1024
            szSize$ = "Bytes"
        Case < 1048576
            szSize$ = "KB"
        Case Else
            szSize$ = "MB"
    End Select
    Return szSize$
End Function

Function getContentSize(hUrl as HINTERNET) as Integer
    Dim As Dword dwSize=BCXSTRSIZE
    Dim szContentLength$, contentSize
   
    HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH, szContentLength$, &dwSize, NULL)
    contentSize = (int)Val(szContentLength)
   
    Return contentSize
End Function

See attached screenshot to see it in action...

AIR.

MrBcx

  • Administrator
  • Hero Member
  • *****
  • Posts: 1966
    • View Profile
Re: DownloadWithProgress
« Reply #1 on: April 17, 2024, 11:16:53 AM »
Gracias Amigo!

It builds with all my BED compilers and runs flawlessly. 

You make it too easy.   ;)