对
this question的回答表明,在delphi中通过类型库导入使用WinHTTP是多么容易.
我为WinHTTP导入了类型库,然后尝试使用该API编写文件下载帮助程序函数.这是我有多远:
我似乎无法弄清楚如何将IWinHttpRequest.ResponseStream(在TLB文件中声明为OleVariant)作为Stream保存到磁盘.
// 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,wr); finally FileStream := nil; fs.Free; end; end; except result := false; // do not raise exceptions. end; end;
摘自WinHTTP_TLB.pas:
IWinHttpRequest = interface(IDispatch) ['{016FE2EC-B2C8-45F8-B23B-39E53A75396B}'] ...... property ResponseStream: OleVariant read Get_ResponseStream;
更新:我现在在调用http.ResponseStream.CopyTo(…)时获得关于ole变体的运行时异常
EOleError 'Variant does not reference an automation object'.
解决方法
Warren,您必须使用
AxCtrls.TOleStream
类来与
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,wr:Int64; FStatus : Integer; OleStream: TOleStream; begin try wUrl := url; http := CoWinHttpRequest.Create; http.open('GET',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.