How to download a file from the web to a local drive (Views: 32)
Problem/Question/Abstract: I want to write an application that can download upgraded versions of itself. Answer: Solve 1: If you are just going to download there is no need to use ActiveX controls. Windows has the function you need already declared in the UrlMon.dll. To download a file to a local disk just use this code. Note: This function is not described in Delphi Help nor in the Win32 Programmer's Reference. uses URLMon; { ... } if URLDownloadToFile(nil, 'http://go.to/masdp', 'c:\index.html', 0, nil) <> 0 then MessageBox(Handle, 'An error ocurred while downloading the file.', PChar(Application.Title), MB_ICONERROR or MB_OK); { ... } Solve 2: Downloading a file is not very difficult, something like: uses Wininet; var InternetBrowserUserAgent: string; {Set it as you like. Win98/IE uses 'Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)' } { ... } function GetInternetStream(URL: string; Stream: TStream): LongInt; type TNetBuffer = array[0..1023] of Byte; PNetBuffer = ^TNetBuffer; var ihConnect, iDocument: HINTERNET; NetBuffer: PNetBuffer; BufferSize: Integer; I: integer; begin Result := -1; ihConnect := InternetOpen(PChar(InternetBrowserUserAgent), LOCAL_INTERNET_ACCESS, '', '', 0); try if ihConnect <> nil then begin iDocument := InternetOpenURL(ihConnect, PChar(URL), nil, Cardinal(-1), INTERNET_FLAG_RELOAD or INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_RAW_DATA, 0); try if iDocument <> nil then begin Result := 0; try New(NetBuffer); repeat InternetReadFile(iDocument, NetBuffer, SizeOf(TNetBuffer), BufferSize); if BufferSize > 0 then begin Result := Result + Stream.Write(NetBuffer^, BufferSize); end; until (BufferSize < SizeOf(TNetBuffer)); finally Dispose(NetBuffer); end; end; finally internetCloseHandle(iDocument); end; end; finally InternetCloseHandle(ihConnect); end; end; If you call this function with a TFileStream, you have the file on your harddisk. If you have a ZIP, you probably want to unzip the file now, use a component that can do this (I think there are some around). The problem is that an application cannot replace itself (because it is write protected while it is running). The solution would be to call another application and terminate the first one. The second one has to update the first one (maybe wait a while until it is really terminated and not write protect any more) and start it again. If you just have to update non-executable files this is much easier. Another solution would be a separate update-application, that the user can call from somewhere (after he has closed the main application). |