Allow backround events while using URLDownloadToFile API

Posted on 2003-03-23
Medium Priority
Last Modified: 2007-12-19
Hello -
I'm trying to implement an update feature for my program.  Part of that requires launching an Updater.exe file, which in turn downloads the new version of the program I'm trying to update.  To download the new program, I've been using the URLDownloadToFile API. It works, but there are 1-2 problems with it.  

The main one is that once the code executes to download a file using this API, all other events HALT, such that if the file is big, a user may think the Updater is frozen, and indeed it has to be Forced to close until it finishes the download...( For example, moving the form, changing focus, clicking other controls, any event within the form)

I tried using DoEvents, but that doesn't really help, as control passes to the API on that line of code, so I can only allow events before or after the download, but NOT during the download...

One possible solution would be a progress bar such that the end-user can see that its doing something, but thats the second issue.  The ONLY way that I could find that *might* allow showing a progress bar during download is using the pCaller and lpfnCB fields of the API.  But from the looks of it, that only works with a Microsoft ActiveX Control...which this is not, + I would need some help on how to use those.

My goal with this is to make a small, light Updater app that basically downloads a file WITHOUT "freezing" during the download, that shows progress of download.

The download itself would be roughly 260 Kb - 500 Kb, maybe 1-3 times a week.
The main app would check a remote text file, determine if there's an update, if there is launch this updater.exe, which then downloads the new program, kills the current program, and launches the new one.

Any tricks for using this API, or suggestions of better ones appreciated...

Question by:elmosiris
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2

Accepted Solution

FunkyMeister earned 225 total points
ID: 8199901
Read up on InternetFileRead, it's much safer and you can actually setup callbacks on this to show progress (it takes a bit of work to use it ASYNC, but it's not impossible).

There are numerous references on the web for this, just search for: "InternetFileRead" "Visual Basic"

You'll get a lot.  I'm using it with some DoEvents to cut down on the non-ASYNC usage, it only pauses during server request/connect (which I also set timeouts for, so even that's not bad).

Author Comment

ID: 8245280
Thanks for that tip... (you must've meant InternetReadFile)... tracked it down, works great, even got it to show a progressbar without callbacks..

Expert Comment

ID: 8246629
Yes, I did.  Silly me, got the name mixed up.  :)  Yes, doing it with InternetREADFile is a breeze.  Plus, you can error check easily as well, know what happened during the transfer, etc.  A lot less "dumbfounded" than URLDownloadToFile.  Glad I could help.
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 11473680

I don't suppose you could share you're findings here???

InternetReadFile is a part of WinInet which is alot more complex than the likes of:

Inet.Protocol = icHTTP
URL = path & filename
FileContents() = Inet.OpenURL(URL, icByteArray)

Expert Comment

ID: 11474048
Taken from the API-Guide for "InternetOpenURL":

Const scUserAgent = "API-Guide test program"
Const sURL = "http://www.microsoft.com/index.htm"
Private Declare Function InternetOpen Lib "wininet" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet" (ByRef hInet As Long) As Long
Private Declare Function InternetReadFile Lib "wininet" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
Private Declare Function InternetOpenUrl Lib "wininet" Alias "InternetOpenUrlA" (ByVal hInternetSession As Long, ByVal lpszUrl As String, ByVal lpszHeaders As String, ByVal dwHeadersLength As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
Private Sub Form_Load()
    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net

    Dim hOpen As Long, hFile As Long, sBuffer As String, Ret As Long
    'Create a buffer for the file we're going to download
    sBuffer = Space(1000)
    'Create an internet connection
    hOpen = InternetOpen(scUserAgent, INTERNET_OPEN_TYPE_DIRECT, vbNullString, vbNullString, 0)
    'Open the url
    hFile = InternetOpenUrl(hOpen, sURL, vbNullString, ByVal 0&, INTERNET_FLAG_RELOAD, ByVal 0&)
    'Read the first 1000 bytes of the file
    InternetReadFile hFile, sBuffer, 1000, Ret
    'clean up
    InternetCloseHandle hFile
    InternetCloseHandle hOpen
    'Show our file
    MsgBox sBuffer
End Sub

Not sure how this would translate in .net.

Expert Comment

ID: 11478761
Thanks FunkyMeister, now all I need to do is work out how to show the progress.

Expert Comment

ID: 11491252
Well, since the InternetReadFile reads based on available data (if the data ready isn't 1000 as above, it returns what it got instead).

Ret will hold the length of the sBuffer, you can then merely find out using header retrieval, how large the file is first.  Which means, whatever data is present, you get, it doesn't wait for 1000 to come in, it returns what's present in the stream on your end and then returns.  If you want to, you can use the return value from InternetReadFile to see what is happening.  It's 1 while it's going through the file.  There's also getting last dll error to give you information as well.  The Inet errors are betweel 12000 and 13000, that I found.

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses
Course of the Month8 days, 17 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question