Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to retrieve a file from Internet via HTTP?
    primarykey
    data
    text
    <p>I want to download a file from Internet and InternetReadFile seem a good and easy solution at the first glance. Actually, too good to be true. Indeed, digging a bit I have started to see that actually there are a lot of issues with it. People are complaining about all kinds of problems when using this code. </p> <p>Problems could appear because:</p> <ul> <li>the application freezes temporarily until the HTTP server responds</li> <li>the application freezes temporarily because the Internet connections breaks</li> <li>the application locks up because the HTTP server never responds</li> <li>the InternetOpen (I just discovered this recently) MUST be called only once during application life time</li> </ul> <p>I could not find a complete example about how to use it properly and robustly. Does anybody have an idea about how to implement it in a separate thread and with a time out? There is another SIMPLE way to robustly download a file from Internet. Though I don't want to complicate my life with very large libraries like Jedi or even Indy.</p> <pre><code>function GetFileHTTP (const fileURL, FileName: String): boolean; CONST BufferSize = 1024; VAR hSession, hURL: HInternet; Buffer: array[1..BufferSize] of Byte; BufferLen: DWORD; f: File; sAppName: string; begin // result := false; sAppName := ExtractFileName(Application.ExeName) ; hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0) ; { be aware that InternetOpen need only be called once in your application!!!!!!!!!!!!!! } TRY hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0) ; TRY AssignFile(f, FileName) ; Rewrite(f, 1) ; REPEAT InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen); BlockWrite(f, Buffer, BufferLen) UNTIL BufferLen = 0; CloseFile(f) ; Result:= True; FINALLY InternetCloseHandle(hURL) end FINALLY InternetCloseHandle(hSession) END; END; </code></pre> <p>Edit: This functions checks if Internet connection is available. It seems to work on Win98 also.</p> <pre><code>{ Are we connected to the Internet? } function IsConnectedToInternet: Boolean; { Call SHELL32.DLL for Win &lt; Win98 otherwise call URL.dll } var InetIsOffline: function(dwFlags: DWORD): BOOL; stdcall; begin Result:= FALSE; if IsApiFunctionAvailable('URL.DLL', 'InetIsOffline', @InetIsOffline) then Result:= NOT InetIsOffLine(0) else if IsApiFunctionAvailable('SHELL32.DLL', 'InetIsOffline', @InetIsOffline) then Result:= NOT InetIsOffLine(0) end; </code></pre> <p>I am using Delphi 7. Many thanks.</p> <hr> <p>Edit:</p> <p>Losing customers because the application hangs at the first start up is the perfect recipe for losing money.</p> <p>Writing your code to be Microsoft platform dependent is bad. You never know if the customer has the IE version x.x installed.</p> <p>Installing stuff into a user's computer is like playing with guns. It will backfire.</p> <p>(see more about this here: <a href="http://thesunstroke.blogspot.com/2010/06/programmig-like-there-is-no-ms-windows.html" rel="nofollow noreferrer">http://thesunstroke.blogspot.com/2010/06/programmig-like-there-is-no-ms-windows.html</a>)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload