Windows 在Delphi中下载文件
谷歌搜索展示了一些如何在Delphi中下载文件的例子,但大多数都有问题,根据我的经验,有一半的时间不起作用 我正在寻找一个简单健壮的解决方案,它可以让我下载一个exe(用于更新我的应用程序),并在下载完成或出错之前保持当前更新线程的执行。这个过程已经线程化了,所以下载代码应该一直保持执行直到完成(希望如此) 这里有两个实现,它们看起来都非常复杂Windows 在Delphi中下载文件,windows,delphi,winapi,download,Windows,Delphi,Winapi,Download,谷歌搜索展示了一些如何在Delphi中下载文件的例子,但大多数都有问题,根据我的经验,有一半的时间不起作用 我正在寻找一个简单健壮的解决方案,它可以让我下载一个exe(用于更新我的应用程序),并在下载完成或出错之前保持当前更新线程的执行。这个过程已经线程化了,所以下载代码应该一直保持执行直到完成(希望如此) 这里有两个实现,它们看起来都非常复杂 1. 2. 第二种方法是使用WinINet(Windows API的一部分)使用Internet资源的标准方法。我经常使用它,而且一直效果很好。我从
1.
2. 第二种方法是使用WinINet(Windows API的一部分)使用Internet资源的标准方法。我经常使用它,而且一直效果很好。我从未尝试过的第一种方法。(两者都不是“非常复杂”。在使用Windows API时,总会有一些额外的步骤。) 如果您想要一个非常简单的方法,您可以简单地调用。您将无法(完全)控制下载,但它非常简单 例如:
URLDownloadToFile(nil,
'http://www.rejbrand.se',
PChar(ExtractFilePath(Application.ExeName) + 'download.htm'),
0,
nil);
为什么不利用印地。如果您使用TIdHTTP,那么它很简单
procedure DownloadFile;
var
IdHTTP1: TIdHTTP;
Stream: TMemoryStream;
Url, FileName: String;
begin
Url := 'http://www.rejbrand.se';
Filename := 'download.htm';
IdHTTP1 := TIdHTTP.Create(Self);
Stream := TMemoryStream.Create;
try
IdHTTP1.Get(Url, Stream);
Stream.SaveToFile(FileName);
finally
Stream.Free;
IdHTTP1.Free;
end;
end;
您甚至可以使用OnWork和OnWorkBegin事件添加进度条
procedure IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;AWorkCountMax: Int64);
begin
ProgressBar.Max := AWorkCountMax;
ProgressBar.Position := 0;
end;
procedure IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64);
begin
ProgressBar.Position := AWorkCount;
end;
我不确定这些事件是否在主线程的上下文中触发,因此,对VCL组件所做的任何更新都可能必须使用tidnotify组件来避免线程问题。也许其他人可以检查一下 使用URLMon
errcode := URLMon.URLDownloadToFile(nil,
PChar('http://www.vbforums.com/showthread.php?345726-DELPHI-Download-Files'),
PChar( 'a:\download.htm'),
0,
nil);
if errcode > 0 then
showmessage('Error while downloading: ' + inttostr(errcode));
对于具有更高版本delphi的用户,您可以使用:
var
http : TNetHTTPClient;
url : string;
stream: TMemoryStream;
begin
http := TNetHTTPClient.Create(nil);
stream := TMemoryStream.Create;
try
url := YOUR_URL_TO_DOWNLOAD;
http.Get(url, stream);
stream.SaveToFile('D:\Temporary\1.zip');
finally
stream.Free;
http.Free;
end;
end;
提示:用
ParamStr(0)
替换Application.ExeName
,以删除对表单
单元的依赖关系。@mjustin:True。但在生产代码中,您无论如何都不希望将文件保存到应用程序的目录中,该目录是只读的(程序文件),除非该程序是可移植的(例如,在U盘上运行)。谢谢您的回答Andreas。我采用了我发布的第二种方法,因为你说这是标准,希望它是可靠的。谢谢你的努力。谢谢@AndreasRejbrand!这正是我要找的!记住这一点;internet Explorer下载历史记录不允许您下载正在下载的文件的最新版本。。因此,使用IE api可能更快,但并不是在所有情况下下载文件的最佳方式。如果文件较大,您可能希望使用文件流而不是内存流。如果您的应用程序仅在更新过程中使用网络,则使用Indy将增加.exe的大小。这基本上不是我八年前的答案的副本吗?:)我不这么认为。