Enregistrer un fichier téléchargé via WinHTTP sur le disque, en utilisant Delphi XE

Une réponse à cette question a montré comment il est facile à utiliser WinHTTP par Type de Bibliothèque importations en delphi.

j'ai importé la bibliothèque de type pour WinHTTP, puis essayé d'écrire une fonction D'aide de téléchargement de fichier en utilisant cette api. Voilà où j'en suis:

Je n'arrive pas à trouver comment sauver la IWinHttpRequest.Responsiestream (déclaré OleVariant dans le fichier TLB) comme Stream, to disk.

// IWinHttpRequest is defined by importing type library of WinHTTP.
// Microsoft WinHTTP Services, version 5.1 (Version 5.1) C:Windowssystem32winhttp.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;

extrait de WinHTTP_TLB.pas:

 IWinHttpRequest = interface(IDispatch)
    ['{016FE2EC-B2C8-45F8-B23B-39E53A75396B}']
    ......
    property ResponseStream: OleVariant read Get_ResponseStream;

mise à jour: je reçois maintenant une exception d'exécution sur les variantes ole, à l'appel à http.ResponseStream.CopyTo(...)

 EOleError 'Variant does not reference an automation object'.
3
demandé sur Community 2011-07-23 00:46:04

1 réponses

Warren, vous devez utiliser la classe AxCtrls.TOleStream pour communiquer le flux de réponse avec le Classes.TFileStream

quelque chose comme ça

IWinHttpRequest.ResponseStream -> TOleStream -> TFileStream

vérifier ce code d'échantillon

{$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.
6
répondu RRUZ 2011-07-22 21:00:55