|
Good work,
I found somewere in the web better example but useing Moniker. I cannot remember the cite, but here is some of the code.
/\/\/\/\/\/\/\/\/\/\/\/\/\
/\/\/\/ IT is part of Delfhi component
/\/\/\/\/\/\/\/\/\/\/\/\/\
TIEDownload = class;
TBSCB = class(TObject,
IUnknown,
IBindStatusCallback,
IHttpNegotiate,
IAuthenticate,
IHTTPSecurity)
private
{ Private declarations }
Info: TInfo;
OutputFile: TFileStream;
FBSCBTimer: TTimer;
FstartTime: TDatetime;
FTimedOut: Boolean;
FCancel: Boolean;
FBindCtx: IBindCtx;
FStream: IStream;
FMoniker: IMoniker;
FSender: TIEDownload;
FRedirect: Boolean;
FGlobalData: HGLOBAL;
FDataSize: Integer;
FTotalRead: Cardinal;
FDataAvailable: Integer;
{ Public declarations }
{IBindStatusCallBack methods}
function OnLowResource(reserved: DWORD): HResult; stdcall;
function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;
szStatusText: LPCWSTR): HResult; stdcall;
function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall;
function OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult; stdcall;
function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc;
stgmed: PStgMedium): HResult; stdcall;
function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall;
function GetPriority(out nPriority): HResult; stdcall;
function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult; stdcall;
{IHTTPNegotiate methods}
function OnResponse(dwResponseCode: DWORD; szResponseHeaders, szRequestHeaders: LPCWSTR;
out szAdditionalRequestHeaders: LPWSTR): HResult; stdcall;
function BeginningTransaction(szURL, szHeaders: LPCWSTR; dwReserved: DWORD;
out szAdditionalHeaders: LPWSTR): HResult; stdcall;
{IAuthenticate methods}
function Authenticate(var hwnd: HWnd; var szUserName, szPassWord: LPWSTR): HResult; stdcall;
{IWindowForbindingUI methods}
function GetWindow(const guidReason: TGUID; out hwnd): HResult; stdcall;
{IHttpSecurity methods}
function OnSecurityProblem(dwProblem: DWORD): HResult; stdcall;
constructor Create(DownloadInfo: TInfo);
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function Download: HRESULT;
procedure ClearAll;
procedure TimerExpired(Sender: TObject);
public
Url: Pwidechar;
Stream: TStream;
Binding: IBinding;
ResponseCode: Cardinal;
function QueryInfo(dwOption: DWORD; var Info: TDateTime): Boolean; overload;
function QueryInfo(dwOption: DWORD; var Info: Cardinal): Boolean; overload;
function QueryInfo(dwOption: DWORD; var info: string): Boolean; overload;
function GetBindResult(out clsidProtocol: TCLSID; out dwResult: DWORD;
out szResult: POLEStr; dwReserved: DWORD): HResult;
destructor destroy; override;
end;
function TBSCB.GetWindow(const guidReason: TGUID; out hwnd): HResult;
begin
if Assigned(FSender.FGetWindow) then Result :=
FSender.FGetWindow(self, guidReason, LongWord(hwnd)) else
Result := S_OK;
end;
function TBSCB.OnSecurityProblem(dwProblem: DWORD): HResult;
begin
if Assigned(FSender.FOnSecurityProblem) then Result :=
FSender.FOnSecurityProblem(self, dwProblem) else
Result := S_OK;
end;
function TBSCB.Authenticate(var hwnd: HWnd; var szUserName,
szPassWord: LPWSTR): HResult;
var
Len: Integer;
begin
Result := S_OK;
if Assigned(FSender.FOnAuthenticate) then Result :=
FSender.FOnAuthentiCate(self, hwnd, szUsername, szPassword) else
begin
if Info.Username <> '' then
begin
Len := Length(Info.Username);
szUsername := CoTaskMemAlloc(Len * 2);
MultiByteToWideChar(0, 0, Pointer(Info.Username), Len, szUsername, Len);
end else szUsername := nil;
if Info.Password <> '' then
begin
Len := Length(Info.Password);
szPassword := CoTaskMemAlloc(Len * 2);
MultiByteToWideChar(0, 0, Pointer(Info.Password), Len, szPassword, Len);
end else szPassword := nil;
end;
end;
function TBSCB.BeginningTransaction(szURL, szHeaders: LPCWSTR;
dwReserved: DWORD; out szAdditionalHeaders: LPWSTR): HResult;
var
sr: TSearchRec;
Action: Cardinal;
s: string;
Size: Longint;
ResumeSupported: Boolean;
x, Len: Integer;
begin
if FCancel or FSender.FCancel then
begin
Result := E_ABORT;
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, nil, Result);
exit;
end;
if Info.Useragent <> '' then S := 'User-agent: ' + Info.UserAgent + #13#10;
if (Info.FileName <> '') then begin
if FindFirst(Info.FileName, faAnyFile, sr) = 0 then
begin
Size := sr.Size;
FindClose(sr);
Info.RangeEnd := 0;
Action := 0;
if Assigned(FSender.OnResume) then
FSender.OnResume(Self, Info.Filename, Action);
case Action of
RESUME_RESPONSE_CANCEL:
begin
Result := E_ABORT;
exit;
end;
RESUME_RESPONSE_OVERWRITE: Info.RangeBegin := 0;
else
Info.RangeBegin := Size;
end;
end else
begin
Info.RangeBegin := 0;
Info.RangeEnd := 0;
end;
end;
if ((Info.RangeBegin <> 0) or (Info.RangeEnd <> 0)) then
begin
S := S + 'Range: bytes=' + IntToStr(Info.RangeBegin) + '-';
if Info.RangeEnd <> 0 then
S := S + InttoStr(Info.RangeEnd) + #13#10
else s := S + #13#10;
end;
if (Info.AdditionalHeader[0] <> '') then for x := 0 to Info.AdditionalHeader.Count - 1 do
S := S + info.additionalheader[x];
Len := Length(S);
szAdditionalheaders := CoTaskMemAlloc(Len * 2);
MultiByteToWideChar(0, 0, Pointer(S), Len,
szAdditionalheaders, Len);
if Assigned(FSender.FBeginningTransaction) then
Result := FSender.FBeginningTransaction(self, szUrl, szHeaders, dwReserved, szAdditionalHeaders) else
Result := S_OK;
FBSCBTimer := TTimer.Create(nil);
FBSCBTimer.OnTimer := TimerExpired;
FBSCBTimer.Interval := Info.TimeOut;
FBSCBTimer.Enabled := True;
FTimedOut := False;
end;
function TBSCB.OnResponse(dwResponseCode: DWORD; szResponseHeaders,
szRequestHeaders: LPCWSTR;
out szAdditionalRequestHeaders: LPWSTR): HResult;
var
Res: HResult;
len: Cardinal;
s: string;
begin
ResponseCode := dwResponseCode;
if QueryInfo(HTTP_QUERY_CONTENT_LENGTH, Len) and (Len = 0) then
begin
Res := S_OK;
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, nil, Res);
Result := E_ABORT;
end else
if (ResponseCode >= 400) and (ResponseCode < 500) or FCancel or FSender.FCancel then
begin
Result := E_ABORT;
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, nil, Result);
end
else
begin
if Assigned(FSender.FOnresponse) then Result :=
FSender.FOnResponse(self, dwResponseCode, szresponseHeaders, szRequestHeaders, szAdditionalRequestHeaders)
else
Result := S_OK;
if (Info.RangeBegin <> 0) and (Info.FileName <> '') then
begin
QueryInfo(HTTP_QUERY_ACCEPT_RANGES, S);
if (S = 'bytes') or (dwResponseCode = 206) then
begin
Outputfile := TFileStream.Create(Info.FileName, fmOpenReadWrite);
Outputfile.Seek(0, soFromEnd);
end else
begin
Outputfile := TFileStream.Create(Info.FileName, fmCreate);
Info.RangeBegin := 0;
end;
end else if Info.FileName <> '' then Outputfile := TFileStream.Create(Info.FileName, fmCreate);
end;
end;
function TBSCB.GetBindInfo(out grfBINDF: DWORD;
var bindinfo: TBindInfo): HResult;
var
PutFile: TFileStream;
Len: Integer;
begin
grfBINDF := Info.BindInfoValue;
with BindInfo do begin
cbSize := sizeof(TBINDINFO);
if FReDirect then
dwBindVerb := BINDVERB_GET else
dwBindVerb := Info.BindVerbValue;
grfBindInfoF := Info.UrlEncodeValue; //I don't think it is supported by Urlmon.dll yet
dwCodePage := Info.CodepageValue;
with SecurityAttributes do
begin
nLength := SizeOf(TSecurityAttributes);
bInheritHandle := Info.InheritHandle;
if Info.Descriptor <> '' then
lpSecurityDescriptor := Pchar(Info.Descriptor) else
lpSecurityDescriptor := nil;
end;
if Info.ExtraInfo <> '' then
begin
Len := Length(Info.ExtraInfo);
szExtraInfo := CoTaskMemAlloc(Len * 2);
MultiByteToWideChar(0, 0, Pointer(Info.ExtraInfo), Len, szExtraInfo, Len);
end else szExtraInfo := nil;
if (Info.BindVerbValue = BINDVERB_PUT) then
begin
PutFile := TFileStream.Create(Info.PutFileName, fmOpenRead);
putfile.Seek(0, 0);
FglobalData := GlobalAlloc(GPTR, PutFile.Size);
FDataSize := PutFile.Size;
putfile.ReadBuffer(Pointer(FGlobalData)^, Putfile.Size);
putfile.Free;
end;
if (Info.BindVerbValue = BINDVERB_POST) then
begin
FglobalData := GlobalAlloc(GPTR, Length(Info.Postdata) + 1);
FDataSize := Length(Info.PostData) + 1;
move(Info.Postdata[1], Pointer(FGlobalData)^, Length(Info.Postdata));
end;
if (Info.CustomVerb <> '') and (dwBindVerb = BINDVERB_CUSTOM) then
begin
Len := Length(Info.CustomVerb);
szCustomVerb := CoTaskMemAlloc(Len * 2);
MultiByteToWideChar(0, 0, Pointer(Info.CustomVerb), Len, szCustomVerb, Len);
end else szCustomVerb := nil;
Fillchar(stgmedData, 0, sizeof(STGMEDIUM));
cbStgmedData := FDataSize;
with StgmedData do
begin
if dwBindVerb = BINDVERB_GET
then Tymed := TYMED_NULL else
Tymed := TYMED_HGLOBAL; // this is the only medium urlmon supports right now
hGlobal := FGlobalData;
IUnknown(unkForRelease) := self;
end;
end;
Result := S_OK;
end;
function TBSCB.GetPriority(out nPriority): HResult;
begin
if FCancel or FSender.FCancel then binding.Abort;
Result := S_OK;
end;
function TBSCB.OnDataAvailable(grfBSCF, dwSize: DWORD;
formatetc: PFormatEtc; stgmed: PStgMedium): HResult;
var
Data: PByte;
BufL, dwRead, dwActuallyRead: Cardinal;
begin
If FStarttime=0 then FStarttime:=Now;
if FCancel or FSender.FCancel then binding.Abort else
begin
FBSCBTimer.enabled := False;
FBSCBTimer.enabled := true;
if (grfBSCF = grfBSCF or BSCF_FIRSTDATANOTIFICATION)
then
if (FStream = nil) and (stgmed.tymed = TYMED_ISTREAM)
then FStream := IStream(stgmed.stm);
dwRead := dwSize - FTotalRead;
dwActuallyRead := 0;
if (dwRead > 0) then
repeat
Data := AllocMem(dwRead + 1);
FStream.Read(Data, dwRead, @dwActuallyRead);
bufl := dwActuallyRead;
if Assigned(FSender.FOnData) then
begin
FSender.FOnData(self, Data, bufl);
end;
if info.filename <> '' then
Outputfile.WriteBuffer(Data^, bufl) else
Stream.WriteBuffer(Data^, bufl);
Inc(FTotalRead, dwActuallyRead);
FreeMem(data);
until dwActuallyRead = 0;
end;
Result := S_OK;
end;
function TBSCB.OnLowResource(reserved: DWORD): HResult;
begin
Result := S_OK;
end;
function TBSCB.OnObjectAvailable(const iid: TGUID;
punk: IUnknown): HResult;
begin
Result := S_OK;
end;
function TBSCB.OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;
szStatusText: LPCWSTR): HResult;
var
Elapsed: string;
temp, _Speed: double;
Speed: string;
Remaining: string;
begin
if FCancel or FSender.FCancel then binding.Abort else
begin
if (ulStatusCode = BINDSTATUS_DOWNLOADINGDATA) and Assigned(FSender.FOnProgress) then
begin
if FStarttime <> 0 then Elapsed := TimeToStr(FStartTime - Now) else
Elapsed := '';
_Speed := ulProgress / (Now - FStarttime) * SecsPerDay * 1000;
Speed := FloatToStr(_Speed);
Speed := Copy(Speed, 1, Pos(Decimalseparator, Speed) + 2) + ' kb/sec';
if ulProgressMax <> 0 then
remaining := TimeToStr((ulProgressMax - ulProgress) / _speed * 1000 * SecsPerDay)
else
Remaining := '';
end;
FRedirect := (ulStatusCode = BINDSTATUS_REDIRECTING);
if Assigned(FSender.FOnProgress) then
FSender.FOnProgress(self, ulProgress + Info.RangeBegin, ulProgressMax + Info.RangeBegin, ulStatusCode, szStatusText,
Elapsed, Speed, Remaining);
end;
Result := S_OK;
end;
procedure TBSCB.TimerExpired(Sender: TObject);
begin
FTimedOut := TRUE;
Binding.Abort;
end;
function TBSCB.OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult;
begin
if FCancel or FSender.FCancel then
begin
Result := E_FAIL;
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, nil, E_ABORT);
end else
begin
Binding := pib;
Result := S_OK;
end;
end;
function TBSCB.OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult;
begin
Result := S_OK;
if FTimedOut then hResult := INET_E_CONNECTION_TIMEOUT;
if info.filename <> '' then
begin
Outputfile.Seek(0, 0);
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, Outputfile, hResult);
end
else
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(Self, stream, hResult);
if (Info.Filename <> '') then
begin
Outputfile.Free;
Outputfile := nil;
end;
if Info.BindInfoValue = Info.BindInfoValue or BINDF_ASYNCHRONOUS then
FSender.FObjList.Remove(Self);
end;
constructor TBSCB.Create(DownloadInfo: TInfo);
begin
inherited Create;
FStarttime:=0;
if (Info.FileName = '') then Stream := TMemoryStream.Create;
info := DownloadInfo;
FSender := TIEDownload(Info.Sender);
Url := Info.Url;
binding := nil;
if not Succeeded(download) then free;
end;
function TBSCB.Download: HRESULT;
var
hr: HRESULT;
begin
FCancel := False;
Result := S_FALSE;
ClearAll;
hr := CreateURLMoniker(nil, URL, FMoniker);
if (hr <> S_OK) then
begin
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(self, nil, hr);
exit;
end;
hr := CreateAsyncBindCtx(0, SELF, nil, FBindCtx);
if (hr <> S_OK) then
begin
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(self, nil, hr);
exit;
end;
hr := IsValidUrl(FBindCtx, URL, 0);
if hr <> S_OK then
begin
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(self, nil, MK_E_SYNTAX);
exit;
end;
hr := FMoniker.BindToStorage(FbindCtx, nil, IStream, fstream);
if (hr <> S_OK) and (hr <> MK_S_ASYNCHRONOUS) then
begin
if Assigned(FSender.FOnComplete) then FSender.FOnComplete(self, nil, hr);
exit;
end else
begin
Result := S_OK;
end;
end;
procedure TBSCB.ClearAll;
begin
binding := nil;
fmoniker := nil;
fbindctx := nil;
FGlobalData := 0;
FTotalRead := 0;
FDataAvailable := 0;
end;
destructor TBSCB.destroy;
begin
if FBSCBTimer <> nil then FBSCBTimer.Free;
if Outputfile <> nil then outputfile.Free;
info.AdditionalHeader.Free;
Stream.Free;
clearall;
inherited;
end;
function TBSCB._AddRef: Integer;
begin
Result := InterlockedIncrement(FSender.FRefCount);
end;
function TBSCB._Release: Integer;
begin
Result := InterlockedDecrement(Fsender.FRefCount);
if Result = 0 then Destroy;
end;
function TBSCB.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;
function TBSCB.QueryInfo(dwOption: DWORD; var Info: Cardinal): Boolean;
var
HttpInfo: IWinInetHttpInfo;
C: Cardinal;
BufferLength: Cardinal;
Reserved, dwFlags: Cardinal;
begin
Info := 0;
Httpinfo := Binding as IWinInetHttpInfo;
if Httpinfo <> nil then
begin
Reserved := 0;
dwFlags := 0;
BufferLength := SizeOf(Cardinal);
Result := not Boolean(httpInfo.QueryInfo(dwOption or HTTP_QUERY_FLAG_NUMBER,
@C, BufferLength, dwflags, reserved));
if Result then Info := C;
end else Result := FALSE;
httpinfo := nil;
end;
function TBSCB.QueryInfo(dwOption: DWORD; var info: string): Boolean;
var
buf: array[0..INTERNET_MAX_PATH_LENGTH] of char;
HttpInfo: IWinInetHttpInfo;
buflength, dwReserved, dwFlags: Cardinal;
begin
Info := '';
dwReserved := 0;
dwFlags := 0;
Httpinfo := Binding as IWinInetHttpInfo;
if Httpinfo <> nil then
begin
buflength := INTERNET_MAX_PATH_LENGTH + 1;
Result := not Boolean(Httpinfo.QueryInfo(dwOption, @buf, bufLength, dwFlags, dwReserved));
if Result then Info := Buf;
end else
Result := FALSE;
httpinfo := nil;
end;
function TBSCB.QueryInfo(dwOption: DWORD; var Info: TDateTime): Boolean;
var
HttpInfo: IWinInetHttpInfo;
SysTime: TSystemtime;
BufferLength: Cardinal;
Reserved, dwFlags: Cardinal;
begin
Info := 0;
Httpinfo := Binding as IWinInetHttpInfo;
if Httpinfo <> nil then
begin
Reserved := 0;
dwFlags := 0;
BufferLength := SizeOf(TSystemtime);
Result := not Boolean(httpInfo.QueryInfo(dwOption or HTTP_QUERY_FLAG_SYSTEMTIME,
@SysTime, BufferLength, dwflags, reserved));
if Result then Info := SystemtimetoDatetime(SysTime);
end else Result := FALSE;
httpinfo := nil;
end;
function TBSCB.GetBindResult(out clsidProtocol: TCLSID;
out dwResult: DWORD; out szResult: POLEStr; dwReserved: DWORD): HResult;
begin
Result := Binding.GetBindResult(clsidProtocol, dwResult, szResult, 0);
end;
|
|
|
|
|
The sourse is from http://www.euromind.com/iedelphi/iedownload.htm
The component can resume downloading.
|
|
|
|
|
Such as the website follows
http://infonode.electrotek.com/dmmcgi.dll?cmd=HomePage
how to pass the authentication infomation?
|
|
|
|
|
I did some googling on URLDownloadToFile, and came across an answer to your question. The page the answer came from was
http://www.autoitscript.com/forum/index.php?showtopic=5840[^]
Answer quoted here:
Matt @ MPCS wrote:
The basic authentication can be done using "http://username:password@mywebaddress" (e.g. "http://joeblow:default1597@www.securewebsite.com"). You would implement that as the URL string.i>
|
|
|
|
|
|
Hi,
According to MSDN, the parameter ulProgressMax in OnProgress Method of IBindStatusCallback has the following explaination.
ulProgressMax
[in] Unsigned long integer that contains the expected maximum value of the ulProgress parameter for the duration of calls to IBindStatusCallback::OnProgress for this bind operation. Note that this value might change across calls to this method. A value of zero means that the maximum value of ulProgress is unknown (for example, in the IMoniker::BindToStorage method when the data download size is unknown).
The reason I gave it here is the clear that this is not at all the size of the file to download. however in most cases it gives you the size of file but this is not a reliable source of getting file size as in some cases, it will only give you the maximum value ulProgress can have.
You are also calculating the percent of download completed from these parameters, which is buggy.
Can you explain the above problem. In my openion the only proper way of getting the file size if in OnDataAvailable method, which is never called
I will be waiting for your comments.
Hardwork is key to success...
Bilal Ahmed
|
|
|
|
|
Your article is very useful.
I'm in ATL download, but I did't find aborting download process.
I made callback class derived by CBindStatusCallback<t>.
Please let me know how I can abort the download..
|
|
|
|
|
I am sorry for my poor English , but I hope you can help me, thank you!
To many website, this method works very well, but to a few of website, such as http://news.sina.com.cn and http://www.xinhuanet.com/newscenter/gj.htm ,it can not work and show error code "0x800401E4 invalidation grammar".
how to resolve this problem?
|
|
|
|
|
I was able to download from both of those sites with no problems, so I don't have an answer for you.
--Mike--
THERE IS NO THERE IS NO BUT THERE IS
MAGIC PIXIE DUST BUSINESS GENIE CODE PROJECT
Homepage | RightClick-Encrypt | 1ClickPicGrabber
"You have Erica on the brain" - Jon Sagara to me
|
|
|
|
|
Is there a way to get the file attributes say size and date before actually downloading?
|
|
|
|
|
Use HttpOpenRequest and HttpQueryInfo to get the file size.
--Mike--
"alyson hannigan is so cute it's crazy" -- Googlism
Just released - 1ClickPicGrabber - Grab & organize pictures from your favorite web pages, with 1 click!
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
Hello there.
I looked at you reply about how to get filesize from internet but I'm not sure how to use HttpOpenRequest and HttpQueryInfo.
If you have time, can you show me a exampel of how to do use these commands?
It would be a great help if you show me that.
Martin
|
|
|
|
|
Hi...
I want to know the default filename which is a parameter of Urldownloadtofile function when url does not has the filename.
thanks.
|
|
|
|
|
Hi, there:
Could you please tell me how to download all the files in a whole website or directory from a http server?
The CFTPFileFind Class is for ftp server, and the CFileFind class is for local machine, is it right?
Thanks
|
|
|
|
|
You can use IE to do it (make the site a favorite, then in its properties, set it to be available offline) or Google for web site rippers
--Mike--
Just released - RightClick-Encrypt v1.4 - Adds fast & easy file encryption to Explorer
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
thanks Mike, that's really cool!
have any idea how big the codeproject is now? hehe...
Patrick
|
|
|
|
|
You cant download a whole set of files in a web site or directory while you dont have "directory list" permision for the web directory. If you have this permision then you could make a function that procces the HTML and download each file one by one. I'am working in an specific offline browser that I will finish soon and maybe put the code in the Code Project. I am using this function and its working fine, thanks Michel
|
|
|
|
|
Does this take advantage of Explorer's cache? If not, do you know any way to do this?
Thanx!
swine
Check out Aephid Photokeeper, the powerful digital
photo album solution at www.aephid.com.
|
|
|
|
|
|
How do you make this NOT use the cache ?
The problem is that if your Temp-folder is full you won't get any error-messages, as IE happily downloads the data to NIL or stalls the download This requires that you check for disk full/enough space on both the TEMP disk and the disk IE finally copies it to, which is less than elegant.
(On a related note, I think it's illogical that the URLDownloadToFile() downloads to the cache, when you have a function URLDownloadToCacheFile() that essentially does the same, unless I've missed something. - But that's more of a question to the MS devs... )
Apart from that; good article/source.
Best regards,
Rune Espeseth
|
|
|
|
|
Did you find solution to bypass the cache and start downloading from the beginning...if yes then please reply here..
|
|
|
|
|
I can't download files via FireWall.
What's problem
mailto:frolovsky@yandex.ru , Please!!!
|
|
|
|
|
|
|
frolovsky wrote:
I can't download files via FireWall.
Maybe the firewall is causing the problem?!?!?!? Can you download files normally?
Regards,
Brian Dela
Run naked in the snow until you're sweating like a stuck pig and can't seem to catch your breath. When the flu becomes pneumonia, they can cure that with a shot. - Roger Wright
|
|
|
|
|