【问题标题】:Save a file downloaded via WinHTTP to disk, using Delphi XE使用 Delphi XE 将通过 WinHTTP 下载的文件保存到磁盘
【发布时间】:2011-10-11 08:59:34
【问题描述】:

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,rd,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'.

【问题讨论】:

标签: delphi download delphi-xe winhttp


【解决方案1】:

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,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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2020-09-21
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 2016-07-22
    • 2013-12-19
    相关资源
    最近更新 更多