Stažení souboru za pomocí WinInet

vložil Radek Červinka 3. ledna 2012 00:40

Sem tam potřebuji stáhnout jednoduchý soubor z webu. Většinou to dělám za pomocí Synapse a nějaké procedury z jednotky httpsend. Člověk ale musí navíc dělat opičky kolem zjišťování proxy - buďto z registru (HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings) nebo za pomocí jednotky ze synapse SynaMisc a procedury GetIEProxy.

Ale zdá se mi, že v případě autokonfigurace proxy ani jeden ze způsobů nefunguje. Existuje ještě možnost stažení souboru přes WinInet, což je součást instalace IE (resp. nyní nejen IE) a používá to část IE a tak je velká šance že to projde přes různé filtry (teda doufám).

Budu se navíc maskovat za IE9 (viz konstanta csAgent), případně si vyberte vlastního agenta na www.whoishostingthis.com/tools/user-agent/. Kód je částečně opravený kód z internetu, používám ho v Delphi XE.

Konstanta INTERNET_OPEN_TYPE_PRECONFIG zaručuje, že se použije nastavení z IE, dále je možno zvolit přímé připojení atd. Ale toto by měla být tutovka. Není to žádný rychlostní zázrak, ale na určité věci to stačí.

Nevýhodou je závislost na další knihovně, která je sice prakticky standardní i ve Wine - ale člověk nikdy neví.


uses
  WinInet;

const
  csAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1;
   WOW64; Trident/5.0)2011-10-16 20:21:07';


function msDownloadFile(const Url: string): Ansistring;
var
  NetHandle: HINTERNET;
  UrlHandle: HINTERNET;
  Buffer: array[0..1024] of AnsiChar;
  BytesRead: dWord;
begin
  Result := '';
  NetHandle := InternetOpen(csAgent, INTERNET_OPEN_TYPE_PRECONFIG,
   nil, nil, 0);

  if Assigned(NetHandle) then
  begin
    UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0,
       INTERNET_FLAG_RELOAD, 0);

    if Assigned(UrlHandle) then
    begin
      FillChar(Buffer, SizeOf(Buffer), 0);
      repeat
        FillChar(Buffer, SizeOf(Buffer), 0);
        InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
        Result := Result + Copy (Buffer, 1, BytesRead);
      until BytesRead = 0;
      InternetCloseHandle(UrlHandle);
    end
    else
      { UrlHandle is not valid. Raise an exception. }
      raise Exception.CreateFmt('Cannot open URL %s', [Url]);

    InternetCloseHandle(NetHandle);
  end
  else
    { NetHandle is not valid. Raise an exception }
    raise Exception.Create('Unable to initialize Wininet');
end;

Tagy: , ,

Praxe

Komentáře

3.1.2012 9:24:08 #

JaroB

Někdy je dobré využít implementaci rozhraní IBindStatusCallback (a ve vnitřních sítích také IAuthenticate) z jednotky UrlMon, protože poskytuje možnost měřidla - gauge při stahování větších souborů, a dá se tím ovlivnit i timeout (samozřejmě se nemusí implementovat všechno, stačí jenom měřidlo).
Použití je pak jednoduché (BindStatusCallback je implementovaný objekt TBindStatusCallback) viz
var BindStatusCallback: TBindStatusCallback;
...
if URLDownloadToFile(nil, PChar(Source), PChar(DownloadedFile), BINDF_GETNEWESTVERSION or BINDF_PRAGMA_NO_CACHE, BindStatusCallback) = s_OK then //soubor stažen

vysvětlení parametrů zde http://msdn.microsoft.com/en-us/library/aa452098.aspx ;

JaroB

3.1.2012 12:26:37 #

radekvoltr

Slape to opravdu dobre a spolehlive (pouzivam spoustu let) az na jeden pripad. Pokud potrebuje proxyna heslo tak to neprochazi. Pozor na to, da se to zpracovat i tak ale uz to neni takto par radek

radekvoltr

4.1.2012 15:53:51 #

Zdeněk Vašků

Klasika. Kolikrát jediná možnost v korporátních sítích a proxynou.

Zdeněk Vašků

5.1.2012 9:28:18 #

<z>

ja bych zas WinInet uz nepouzil ... mel sem s tim dost problemy s antiviry a obcas se to na ruznych pocitacich chova "divne", hlavne kdyz je to jadro necim nevysvetlitelne "poskozene" :)

<z>

23.3.2012 20:05:40 #

Safrad

Pripadne lze pouzit TDownLoadURL v unite ExtActns, coz je objekt volajici URLDownloadToFile.

Safrad

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců