问题描述
的答案显示,通过Delphi中的类型库导入使用WinHTTP是多么容易
An answer to this question showed how easy it is to use WinHTTP via Type Library imports in delphi.
我导入了WinHTTP的类型库,然后尝试使用该api编写一个File Download helper函数。这是我有多远:
I imported the type library for WinHTTP, and then tried to write a File Download helper function using that api. Here's how far I got:
我似乎无法弄清楚如何将IWinHttpRequest.ResponseStream(在TLB文件中声明为OleVariant)作为Stream保存到磁盘
I can't seem to figure out how to save the IWinHttpRequest.ResponseStream (declared as OleVariant in the TLB file) as Stream, to disk.
// IWinHttpRequest is defined by importing type library of WinHTTP.
// Microsoft WinHTTP Services, version 5.1 (Version 5.1) C:\Windows\system32\winhttp.dll
function Download(const url, filename: String): Boolean;
var
http: IWinHttpRequest;
wUrl: WideString;
fs:TFileStream;
FileStream:IStream;
sz,rd,wr:Int64;
begin
try
wUrl := url;
http := CoWinHttpRequest.Create;
http.open('GET', wurl, False);
http.send(EmptyParam);
FStatus := http.status; // 200=OK!
result := FStatus=200;
if result then
begin
fs := TFileStream.Create(filename, fmCreate, fmShareExclusive );
try
FileStream := TStreamAdapter.Create(fs, soReference) as IStream;
sz := http.ResponseStream.Size;
http.ResponseStream.CopyTo(FileStream,sz,rd,wr);
finally
FileStream := nil;
fs.Free;
end;
end;
except
result := false;
// do not raise exceptions.
end;
end;
摘自WinHTTP_TLB.pas:
Excerpt from WinHTTP_TLB.pas:
IWinHttpRequest = interface(IDispatch)
['{016FE2EC-B2C8-45F8-B23B-39E53A75396B}']
......
property ResponseStream: OleVariant read Get_ResponseStream;
更新:我现在得到一个关于ole变体的运行时异常,在调用 http.ResponseStream.CopyTo(...)
Update: I now get a runtime exception about ole variants, at the call to http.ResponseStream.CopyTo(...)
EOleError 'Variant does not reference an automation object'.
推荐答案
Warren,你必须使用类来汇总响应流 Classes.TFileStream
Warren, you must use the AxCtrls.TOleStream
class to comunicate the response stream with the Classes.TFileStream
这样的事情
IWinHttpRequest.ResponseStream -> TOleStream -> TFileStream
查看此示例代码
{$APPTYPE CONSOLE}
uses
Variants,
ActiveX,
Classes,
AxCtrls,
WinHttp_TLB,
SysUtils;
function Download(const url, filename: String): Boolean;
var
http: IWinHttpRequest;
wUrl: WideString;
fs:TFileStream;
HttpStream :IStream;
sz,rd,wr:Int64;
FStatus : Integer;
OleStream: TOleStream;
begin
try
wUrl := url;
http := CoWinHttpRequest.Create;
http.open('GET', wurl, False);
http.send(EmptyParam);
FStatus := http.status; // 200=OK!
result := FStatus=200;
if result then
begin
HttpStream:=IUnknown(http.ResponseStream) as IStream;
OleStream:= TOleStream.Create(HttpStream);
try
fs:= TFileStream.Create(FileName, fmCreate);
try
OleStream.Position:= 0;
fs.CopyFrom(OleStream, OleStream.Size);
finally
fs.Free;
end;
finally
OleStream.Free;
end;
end;
except
result := false;
// do not raise exceptions.
end;
end;
begin
try
Download('http://foo.html','C:\Foo\anyfile.foo');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
这篇关于使用Delphi XE将通过WinHTTP下载的文件保存到磁盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!