Updated 18 May 2010: The IBindStatusCallback events for URLDownloadToFile are in a class module for easier use/portability. The class now supports download progress bar(s) AND CANCEL with 5 extra events exposed. Now you can add progress bars to your downloads... and free your app from waiting while the file(s) download. I have included an easily modifiable download window to show the progress of your downloads while your app does something else (see the screen shot). It will do multiple downloads with progress. I give you my personal guarantee that you'll find nothing like this on PSC! I did not write this code for this purpose, but you could easily use this code to download a list of updated files (from the internet), then parse the file list and 'auto-update' the files on the local computer. I have also included a DeleteUrlCacheEntry routine from the Wininet api to force a 'fresh copy' download from the internet. Otherwise, URLDownloadToFile will often download a local copy of the requested file that is cached in IE. The project DOES need a type library (freely downloaded) and complete instructions are in the zip. The type lib. is NOT distributed with your app... needed parts are compiled into your project by VB. As is my want, there are more comments than code. If you just started writing VB code this morning, you can download this dude and have it running in 5 minutes AND you'll understand the whole process in 10 minutes! Semi-Guaranteed as usual! BE SURE TO READ THE READ_ME_FIRST.TXT File for instructions on how to get and install the FREE type library needed!
Your most ardent admirer,
'Windows API/Global Declarations for :A URLDownloadToFile Demo WITH PROGRESS bar/CANCEL Update: 18 May 2010
Several, all well documented/commented.
See the zip
Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come
out every day, so no prevention program can catch 100% of them. For your own safety, please:
Re-scan downloaded files using your personal virus checker before using it.
NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
Scan the source code with Minnow's Project Scanner
If you don't have a virus scanner, you can get one at many places on the net
Terms of Agreement:
By using this code, you agree to the following terms...
You may use
this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
You may link to this code from another website, but ONLY if it is not wrapped in a frame.
You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
It occurs to me that I forgot to explain modality issues in the read me:
1) You do not need to launch the second form (as in the demo). It should run freely in one form if the IBindStatusCallback events are exposed (as in the function). Of course, you would need to move the function code to your single form.
2)If you DO use a second window (as in the demo)... if you launch the 2nd window modally with ownership, the 2nd window will set there forever and do nothing untill it is closed by the calling form or other method. I can not see how this would ever be useful. Always launch it as: vbmodeless, owner (if you want the function to report success/failure.
Finally, if you examine the Form_DblClick event for the frmDnLoad.frm, you'll see a backdoor exit I placed there for de-bugging events just like described above. You will probably want to remove that code!
That's all I can think of for now. Hope someone out there finds this code useful!
CptnVic (If this comment was disrespectful, please report it.)
If you read the readme file, it explains how to obtain and implement the library.
The author of the library is kind enough to share it, but requests that it not be published on another site. He is a MS MVP... so such a request is not unusual.
At least you left a comment! Thanks for downloading! CptnVic (If this comment was disrespectful, please report it.)
4/11/2006 1:05:49 PM:
Excellent piece of work...well done...it works and it works just perfect...(CptnVic time to start learning to spell it with K ;))...kidding aside i think this one deserves 5 globes period. (If this comment was disrespectful, please report it.)
4/11/2006 7:37:46 PM:
Me again...I just realised u're an excellent programmer!...and btw about ur comment in the text file, a true engineer is not someone who builds everything from the scratch...rather is someone who has the ability to make good use of what's available!...and sir let me emphasize that u R truly an engineer!...thank u once again for sharing...PSC needs more pro programmers like u!...god bless (If this comment was disrespectful, please report it.)
Excellent piece of compilation. As you seem to have a huge knowledge of this area - any idea how I might use this or other to downloadurl to program, rather than file? something like the wininet internetreadfile that currently is blocked on my company computers
Well done anyway and I like the fact you should read the Readme!!!! (If this comment was disrespectful, please report it.)
I love the project. I'm curious how one would cancel a download currently in progress. MSDN says that IBindStatusCallback::OnProgress must return E_ABORT to signal an aborted transfer. Since I don't know how to make Private Sub IBindStatusCallback_OnProgress(...) return a value, I tried converting it to a Private Function. However, I then get an error stating "Compile error: Procedure declaration does not match description of event or procedure having the same name"
Is this something that I can work around or does the type lib need to be updated to change the subs to functions? Any input would be greatly appreciated. (If this comment was disrespectful, please report it.)
Alan: I am less sure than ever about what it is that you want to accomplish.
InternetReadFile: you literally buffer data from the source until the source is depleted. Is streaming data your goal?
In this case, the data stream is known to be serial. A file, is received in order from string(0) -to-> string(last).
Such is not necessarily the case with URLDownloadToFile where Windows handles the buffering irrespective of the data type received (it can be ANY type of file). This data could be in "packet" type bundles that may be "out of order" until final binding occurs.
If streaming data is your goal, then URLDownloadToFile is a bad method for you. The IBindStatusCallback is an "AddressOf" type pointer through which information about the file download is passing through. The literal file portions are not part of the data stream seen by IBindStatusCallback (that would be terribly inefficient).
Can you give me a simple example of what you want to do?
Regards, CptnVic (If this comment was disrespectful, please report it.)
Hy. I will install it tomorrow. Do anybody know how to handle "Site forwarding"? How to read out a URL if the given URL goes to a forwarded URL-page? (If this comment was disrespectful, please report it.)
I was trying to read an XML webpage from the internet into an app (no temp file). While URLDownloadToFile worked, the WinInet API did not - blocked by the firewalls.
I was wondering if there was a similar call to URLDownloadToFile that would pull the data, at the end of download, straight into the app.
I didnít realise the difference with the basic processing by Windows of these commands.
Anyway, I found a different method anyway - MSXML. Basically it appears my internet access from the application needed to be high enough in the 'hierachy' to appear to the firewall as Internet Explorer, but lower than the WebBrowser control which doesn't let you view the source effectively since it is already formatted. MSXML provides this although obviously restricts the deployment systems that do not need an installation package slightly further as it requires IE5.
Thanks anyway and I hope the issues help someone else!
Regards, Alan (If this comment was disrespectful, please report it.)
YIKES! I noticed that when I ported this from some of my original code... I had forgotten to reset dwReserved to BINDF_GETNEWESTVERSION.
Passing 0 to dwReserved causes the function to try to retrieve the cached copy of the file if it exists... BINDF_GETNEWESTVERSION instructs the function to get the file from the szURL location. The BINDF_GETNEWESTVERSION flag is already declared in the class module... just not implemented as it is.
Therefore, in the StartTheStinkinDownLoad function (in the class module) the call should be: '------------------------- DownLoadResult = olelib.URLDownloadToFile(Nothing, File2DownLoad, _ File2Save, BINDF_GETNEWESTVERSION, Me) '-------------------------
Since the class calls DeleteUrlCacheEntry prior to downloading the new file, this really shouldn't make any difference. However, it is crazy to delete a cached copy, then try to download that copy again!
CptnVic (If this comment was disrespectful, please report it.)
thank you for this code I was trying to use this years ago and finally gave up not being able to get the functions to work so I could trap the progress <3 (If this comment was disrespectful, please report it.)
Thanks for the code, however, it does not delete the cache, even when using DeleteVicCache. I'm thinking that perhaps the code writes the cache to a different location, which is why it can't use the IE function to delete it. I've tested this many times, downloading large (22mb) files. If I cancel the download, then try again, it picks up where it left off. Any suggestions as to how to implement deleting the cache? (If this comment was disrespectful, please report it.)
If you want to download a file - but not save the file to disk, the Wininet.dll is probably your best bet.
With regards to Luca's question, you can combine: InternetOpen, InternetOpenUrl, InternetReadFile, and InternetCloseHandle api's to download a file to a string (for example) and then place the string contents into a textbox - without saving to disk.
Let me know if you need some example code to do this... and I'll post some.
Regards, CptnVic (If this comment was disrespectful, please report it.)
Donít bother with thisÖ code is waaaaay 2 long and complicated 4 what it does and on the top of that require external libraries (?!?) You can do same thing with 5-10 lines of code. Submissions like this are just waist of time. (If this comment was disrespectful, please report it.)
Just love the demo, it works like a charm! However, in testing your unmodified code, I notice that after every download is complete, I get a "Holy Moly" error of 0 of unknown type. I found this to be coming from the hresult parameter of the IBindStatusCallback_OnStopBinding routine. hresult is returned as 0, so I get the error box. But, the progress meter has finished, and I get the file! What might be causing this? Thanks! (If this comment was disrespectful, please report it.)
CptnVic, its pathetic how so called programmers from US always show off with thereís grammar school skills when they canít code properly. Is your last resource of making your point really a spell check? I would like 2 see you learning some foreign language yourself, lol. Your code is still horrible in my opinion. I posted my comment not to offend you but to save some time 2 others (If this comment was disrespectful, please report it.)
DDPP: A search for DDPP returns NO code, which is somewhat surprising given your own estimation of your programming skills. Furthermore, I still await the "5-10 lines of code" that can do the same - accessing the callback. Time to put up or shut up. (If this comment was disrespectful, please report it.)
CpnVic, Amazing code! Thanks so much for sharing. Although I don't like using 3rd-party controls because of the exact problem I am having. Occaissionally I get a non-recreateable fatal crash when downloading files using this code. Microsoft says faulting module is Olelib.tlb. I can't trace the code in the IDE or exe as it is a very sudden un-traceable crash. I use XP and olelib.tlb version 1.81. Otherwise works FANTASTIC! no download-lockups and beautiful progress. -Very nice! Any ideas? Joe (If this comment was disrespectful, please report it.)
David: Looks like I didn't handle S_OK=0... when I get a few minutes, I'll repair error handler and re-post. Joe: Still looking into your problem. (If this comment was disrespectful, please report it.)
CptnVic, Want to let ya know that my problem was caused by the DoEvents allowing a 2nd download to interrupt the 1st download. I use a Drag and Drop interface so I needed to write code to cancel a Drop request if a download was in progress. That fixed it! -Great code CptnVic! Also, I want to tell ya that I DO need to distribute Olelib.tlb for my app to run. -Joe Sova
P.S. Ya look a lot like Al Bundy! (If this comment was disrespectful, please report it.)
Really, really nice job! Your code probably saved me two weeks of work on a Wii box art feature I wanted to implement. Five big globes from me. Thanks for sharing. (If this comment was disrespectful, please report it.)
you seem to have good knowledge of file transfer via internet... I hope you could help me in my problem...
When we download a file from the internet using web browser or any professional file download application.. they automatically get the name from the URL (the name of the file by which it is stored in the server)... I get the header using the Inet control but there wasn't any filename mentioned there... could you please help me and tell me how to get the filename from the URL... (If this comment was disrespectful, please report it.)
max (If this comment was disrespectful, please report it.)
Add Your Feedback
Your feedback will be posted below and an email sent to
the author. Please remember that the author was kind enough to
share this with you, so any criticisms must be stated politely, or they
will be deleted. (For feedback not related to this particular code, please
click here instead.)